web-dev-qa-db-ja.com

MySQLはテーブル内のどこでも選択しません

同じ主キーを持つ2つのテーブル(AとB)があります。 BではなくAにあるすべての行を選択したい。次のように動作します。

select * from A where not exists (select * from B where A.pk=B.pk);

しかし、それは非常に悪いようです(Aでは100k行のみで2秒、Bでは3-10k少ない)

これを実行するより良い方法はありますか?おそらく左結合として?

select * from A left join B on A.x=B.y where B.y is null;

私のデータでは、これはわずかに速く(〜10%)実行されるようですが、一般的にはどうですか?

52
BCS

2番目の例の形式でクエリを使用します。通常、結合は相関サブクエリよりもスケーラブルです。

35
Bill Karwin

最後の発言が最善の方法だと思います。試すこともできます

SELECT A.*    
from A left join B on 
    A.x = B.y
    where B.y is null
55
Nick Berardi

結合は一般に高速です(MySQLで)が、まだゆっくりと動いていることがわかった場合は、インデックススキームも考慮する必要があります。通常、外部キーとして設定されたフィールド(INNODBを使用)には、すでにインデックスが設定されています。 MYISAMを使用している場合は、ONステートメントの列にインデックスが付けられていることを確認し、WHERE句の列もインデックスの最後に追加して、カバーインデックスにすることを検討してください。これにより、エンジンはインデックスに必要なすべてのデータにアクセスできるようになり、元のデータに2回目のラウンドトリップを行う必要がなくなります。これは挿入/更新/削除の速度に影響しますが、クエリの速度は大幅に向上する可能性があることに注意してください。

2
ChoNuff

「where table2.id is null」タイプの条件で左結合も使用します。

確かに、ネストされたクエリオプションよりも効率的であるようです。

2
Dave Rix