5

かなり巨大なテーブル (~100 GB) に対して実行する削除クエリがいくつかあり、それらを可能な限り最適化したい:

delete from table1 where column1 < date_sub(now(), interval 100 hour);

column1 はdatetime列です。この列のインデックスを作成すると、削除が高速化されると思います。それ以外に、ここで何かできることはありますか? 関数を使用するdate_sub()とクエリが遅くなりますか? クエリを実行する前にその値を計算する必要がありますか?

delete from table2 where column2 = x;

column2 は table2 の主キーであるため、mysql のドキュメントによると、既にインデックスになっています。私の質問は次のとおりです。インデックスの種類はPRIMARY、それは と同じINDEXですか? INDEX高速化のために別のインデックスを作成する必要がありますか?

delete from table3 where column3 = y;

table3 には、column3 と column4 の複合主キーがあります。主キーのインデックスはありますが、削除クエリは列 4 を使用しないため、列 3 だけに別のインデックスを作成する必要がありますか? または結合された主キーがそれを行うでしょうか?

これらはかなり基本的な質問だと思いますが、私の状況に固有の明確な答えが見つからなかったので、助けていただければ幸いです!

4

2 に答える 2

11

そのテーブルの行の大部分を削除することを意図している場合、DELETE保持したい行だけを複製テーブルにコピーし、DROP TABLEまたはTRUNCATEを使用して元のテーブルをはるかに迅速に消去することがよくあります。

インデックスは、削除する必要がある行を見つけるのに役立つ場合がありますが、削除するにはインデックスを更新する必要があります。多くの行を削除した後、インデックスが不均衡になる可能性があり、OPTIMIZE TABLE.

関数はDATE_SUB()定数式 (行ごとに変化しない) であるため、クエリ オプティマイザーはそれを因数分解して計算を 1 回実行するのに十分なほどスマートである必要があります。

主キー用に追加のインデックスを作成する必要はありません。主キー制約は、非主キー インデックスと同じ利点をもたらすインデックスを暗黙的に作成します。

複合インデックスは、検索基準がインデックスの左端の列を参照する場合、おそらく単一列のインデックスと同じくらい有用です。「おそらく」注意点は、個々のインデックス ノードが大きくなるため、インデックスをキャッシュするためにより多くのメモリが必要になるためですが、これは十分に小さいため、他の単一列インデックス全体を作成することはできません。

于 2009-12-31T22:59:27.717 に答える
2

この列のインデックスを作成すると、削除が高速化されると思います。

不正解です。将来使用するためにインデックスを任意の値にするには、同じインデックスを更新する必要があるためです。

date_sub() 関数を使用するとクエリが遅くなりますか?

いいえ、列の値に基づいていないので問題ありません。列値に対して実行される関数により、索引が列に存在する場合は使用できないことが保証されます。

インデックスの種類は「PRIMARY」ですが、「INDEX」と同じですか?

それはそうであり、プライマリ部分は、そのインデックスの値も一意であることを保証します。

高速化のために「INDEX」のような別のインデックスを作成する必要がありますか?

いいえ、あなたはしません。また、MySQL は、タイプに応じて、1 つのテーブルで定義できるインデックスの合計サイズを制限します。767 バイトは、InnoDB テーブルのインデックス プレフィックスの制限として規定されています。MyISAM テーブルの場合は 1,000 バイトです。

table3 には、column3 と column4 の複合主キーがあります。主キーのインデックスはありますが、削除クエリは列 4 を使用しないため、列 3 だけに別のインデックスを作成する必要がありますか? または結合された主キーがそれを行うでしょうか?

両方のセットアップをテストして決定します。私自身、追加のインデックスは必要ないと思います。

于 2009-12-31T22:51:29.393 に答える