1 から 10 までの値を取る列を持つテーブルがあるとします。9 と 10 を除くすべての値を持つ列を選択する必要があります。このクエリを使用すると、(パフォーマンスに関して) 違いはありますか?
SELECT * FROM tbl WHERE col NOT IN (9, 10)
そしてこれは?
SELECT * FROM tbl WHERE col IN (1, 2, 3, 4, 5, 6, 7, 8)
1 から 10 までの値を取る列を持つテーブルがあるとします。9 と 10 を除くすべての値を持つ列を選択する必要があります。このクエリを使用すると、(パフォーマンスに関して) 違いはありますか?
SELECT * FROM tbl WHERE col NOT IN (9, 10)
そしてこれは?
SELECT * FROM tbl WHERE col IN (1, 2, 3, 4, 5, 6, 7, 8)
DBMS が対応する列のインデックスを使用する可能性が高いため、"IN" を使用します。
「NOT IN」も理論的にはインデックスの使用に変換できますが、より複雑な方法で DBMS が「オーバーヘッド時間を費やす」ことはありません。
パフォーマンスに関しては、常にコードをプロファイリングする必要があります (つまり、クエリを数千回実行し、ある種のstopwatch
. Sampleを使用して各ループのパフォーマンスを測定します)。
ただし、ここでは、将来のメンテナンスを改善するために最初のクエリを使用することを強くお勧めします。ロジックは、9 と 10 以外のすべてのレコードが必要だということです。値 11 をテーブルに追加して 2 番目のクエリを使用すると、アプリケーションのロジックが壊れて、もちろんバグにつながります。
編集:これはphpとしてタグ付けされていたので、phpでサンプルを提供したことを覚えていますが、間違っている可能性があります。あなたが使用している言語でそのサンプルを書き直すことは難しくないと思います。
列が NULL 可能である場合、Oracle が NOT IN を使用していくつかのクエリを最適化するのに問題があるのを見てきました。どちらの方法でもクエリを記述できる場合、私に関する限り、IN が優先されます。
定数のリストについては、MySQL は内部的にコードを次のように展開します。
SELECT * FROM tbl WHERE ((col <> 9 and col <> 10))
もう一方も同じで、=
代わりに 8 回です。
そうです、最初のものはより速く、比較が少なくなります。それが測定可能である可能性はごくわずかですが、少数の定数比較のオーバーヘッドは、SQL の解析とデータの取得の一般的なオーバーヘッドと比較して何もありません。