2011-01-13 12 views
5

はのは、カラムAのインデックスがあり、私は二つの列AとBを持つテーブルがあると仮定しますが、列B に私のような数百万のクエリを発行したくない:どこからでもありますMySql UPDATEの最適化ですか?

UPDATE t1 SET b=b1 WHERE a=a1; 
UPDATE t1 SET b=b2 WHERE a=a2; 
.... 

を各ユニーク値aに対応する1〜100,000行。平均で約100です。

これらの行については、平均で60%の更新ステートメントは変更されません。bには既に望ましい値が設定されています。 30%の更新では、一致する行はどれも変更されません。

このような文を使用することは意味がありますか?

UPDATE t1 SET b=b1 WHERE a=a1 AND b<>b1; 

それは、ディスクへの不要な書き戻しをなくすことで、プロセスをスピードアップウィルやMySQL 5は何も変わっていないされており、ディスクへの書き込みする必要がないことを認識するのに十分なスマートですか?

答えて

4

を含めてください、MySQLは読まなければならない場合(ディスク上にあるかキャッシュ/バッファープールにあるかにかかわらず)。どちらの場合でも、MySQLはaのインデックスを開始点として使用します。いずれの場合でも、すでに宛先値がbの場合、MySQLは行を更新しません。したがって、私はMySQLがb<>b1節を持つことによって利益を得る方法を見ません。ワークロードとデータセットに応じて、間違いなく

、(その中にb<>b1付き)クエリかもしれない利益あなたが(そのために)ab上の複合インデックスであることをa上のインデックスを変更した場合。この場合、(具体的には)の更新が必要な行(つまり、前述の30%と60%を大文字にする)を見つけるためにディスクをヒットする必要はありません(またはキャッシュ/バッファプールを確認する必要はありません)。今述べたように、インデックスはbにアップデートごとにアップデートする必要がありますので、ですが、トレードオフに値すると思われます。

0

余分なフィルタを追加する必要があります。 Mysqlはスマートで値が同じであれば値を更新しませんが、このチェックを外す方が良いでしょう。これは、クエリによって「影響を受けた」行の数を確認することで確認できます。

0

私はこの便利なCASE

update t1 
set b= 
    case a 
    when a=a1 then b1 
    when a=a2 then b2 
    when a=a3 then b3 ... 
    end; 

希望を使用して、単一の更新に複数の更新を組み合わせることを考えて、それはひどい遅い、いずれの場合も、について説明