2013-06-11 1 views
5

次のクエリがMySQL 5.1のINNODBテーブルで実行された場合、私には不明です(MySQLドキュメントを読むことによって)バッチ内のすべての行を内部的に更新(合計5000件)するか、またはすべての行をロック解除します。データベースの負荷が非常に大きいので、これは非常に重要です。SELECTを使用してUPDATEを実行すると、各行またはすべてのSELECTレコードがロックされます

UPDATE `records` 
INNER JOIN (
    SELECT id, name FROM related LIMIT 0, 5000 
) AS `j` ON `j`.`id` = `records`.`id` 
SET `name` = `j`.`name` 

私は必ずそれがそうであるようにする方法を知らないと私はそれが行ごとにあることを期待しますがしたい、私はより深い知識を持つ人を依頼することを決めました。これが当てはまらず、dbがセット内のすべての行をロックする場合は、理由を説明すると感謝します。

+0

トランザクションを使用していますか? (自動コミット=オフ)? ps:あなたのクエリは意味的に正しいですか? – Sebas

+0

これはおそらくすべての行をロックします。なぜなら、これはMySQLのロールバック方法だからです。 – GolezTrol

+0

ああ、もちろん、テーブルの種類によって異なります。http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html – GolezTrol

答えて

3

UPDATEはトランザクションで実行されています。これはatomic操作です。つまり、行のいずれかが失敗した場合(たとえば、一意の制約のため)、5000行も更新されません。これは、トランザクションデータベースのACIDプロパティの1つです。

このため、UPDATEは、トランザクション全体のすべての行をロックします。それ以外のトランザクションでは、現在の値に基づいて行の値をさらに更新することができます(更新レコードの設定値= value * '2')。この文は、最初のトランザクションがコミットするかロールバックするかによって異なる結果を生成します。このため、最初のトランザクションが5000回の更新をすべて完了するのを待つ必要があります。

ロックを解除する場合は、更新を(より小さい)バッチで実行してください。

P.S. autocommitは、各文が自分のトランザクションで発行されたかどうかを制御しますが、単一の問合せの実行には影響しません。

関連する問題