web-dev-qa-db-ja.com

「NOT IN」の代替案

このテーブルの主キーであるidというフィールドを取得したテーブルAがあります。また、主キーとしてidというフィールドを持つBというテーブルもあります。

ここで、id値がテーブルB idフィールド値の値として存在しないテーブルAからすべての行を取得します。

最初のクエリは次のようになりました。

SELECT a.id FROM a WHERE a.id NOT IN (SELECT DISTINCT b.id FROM b)

次に、速度を向上させるために、次のようなクエリを作成します。

SELECT a.id FROM a LEFT JOIN b ON a.id = b.id WHERE b.id IS NULL

これで、テーブルAに60万行、テーブルBに40万行があり、処理が非常に遅くなっています。この種の操作で実行するのに適したクエリはありますか、それとも問題を解決するためのより良い方法がありますか?ヒントやポインタはありますか?

5
Johnny000

join_buffer_size を増やす必要があります。 join_buffer_sizeとは何ですか?

プレーンインデックススキャン、レンジインデックススキャン、およびインデックスを使用せず、フルテーブルスキャンを実行する結合に使用されるバッファの最小サイズ。通常、高速結合を実現する最良の方法は、インデックスを追加することです。 インデックスの追加が不可能な場合は、join_buffer_sizeの値を増やして、完全な結合を高速化します。1つの結合2つのテーブル間の完全結合ごとにバッファが割り当てられます。インデックスが使用されていない複数のテーブル間の複雑な結合の場合、複数の結合バッファが必要になる場合があります。

クエリが簡単になるため、この文を強調表示しました。あなたは私が両方のテーブルですでにインデックス付けされていると仮定している整数で結合を行っています。テーブルbのIDがインデックス化されていない場合は、できるだけ早くインデックス化してください。

join_buffer_size を4Mに増やすことをお勧めします。

セッションで join_buffer_size を変更してクエリを再実行できます

SET join_buffer_size = 1024 * 1024 * 4;
SELECT a.id FROM a LEFT JOIN b ON a.id = b.id WHERE b.id IS NULL;

GIT IT A TRY !!!

2
RolandoMySQLDBA