以下のどれがより効率的か知りたいですか?
SQL Serverは結果セットを大きなIN
ステートメントに変換すると考えているため、IF
の使用には常に少し注意を払っています。結果セットが大きい場合、パフォーマンスが低下する可能性があります。結果セットが小さい場合、どちらが望ましいかはわかりません。結果セットが大きい場合、EXISTS
はより効率的ではありませんか?
WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
vs.
WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2])
EXISTS
は、エンジンがヒットを検出すると、条件が真であることが判明すると検索を終了するため、高速になります。
IN
を使用すると、さらに処理する前にサブクエリからすべての結果を収集します。
受け入れられた答えは近視眼的であり、質問はそれで少し緩いです:
1)カバーインデックスが左側、右側、または両側に存在するかどうかを明示的に言及しない。
2)どちらも、左側の入力セットと右側の入力セットのサイズを考慮しません。
(質問は、全体的に大きなresult setに言及しているだけです)。
オプティマイザーは、(1)と(2)による大幅なコストの違いがある場合に「in」と「exists」の間を変換するのに十分スマートであると信じています。右側のシーク可能なインデックス)。
両方のフォームを内部で結合フォームに変換し、結合順序を逆にし、推定行数(左右)と左、右、または両側のインデックスの存在に基づいて、ループ、ハッシュ、またはマージとして実行できます。
私はSQL Server 2005と2008でいくつかのテストを行いましたが、EXISTSとINの両方で、他の人が述べたように、まったく同じ実際の実行計画で戻ります。オプティマイザーが最適です。 :)
ただし、クエリを正しく表現しないと、EXISTS、IN、およびJOINが異なる結果を返す場合があることに注意してください。 http://weblogs.sqlteam.com/mladenp/archive/2007/05 /18/60210.aspx
通常、実行計画はこれらの場合に同一になりますが、オプティマイザーがインデックスなどのその他すべての側面をどのように考慮に入れるかを見るまで、あなたは本当に知りません。
したがって、INはEXISTSと同じではなく、同じ実行計画を生成しません。
通常、EXISTSは相関サブクエリで使用されます。つまり、EXISTS内部クエリを外部クエリと結合します。外部クエリ結合と内部クエリ結合を解決し、where句を一致させて両方を結合する必要があるため、結果を生成するためのステップが追加されます。
通常、INは内部クエリと外部クエリを相関させずに使用されます。これは1つの手順で解決できます(最良の場合)。
このことを考慮:
INを使用し、内部クエリの結果が数百万の異なる値の行である場合、EXISTSクエリがパフォーマンスに優れている(外部クエリと結合するための適切なインデックスがある)場合、おそらくEXISTSよりも低速に実行されます。
EXISTSを使用し、外部クエリとの結合が複雑な場合(実行に時間がかかり、適切なインデックスがありません)、外部テーブルの行数だけクエリが遅くなります。完了までの推定時間は数日になる場合があります。特定のハードウェアで行数が許容できる場合、またはデータのカーディナリティーが正しい場合(たとえば、大きなデータセットのDISTINCT値が少ない場合)、INはEXISTSよりも高速に実行できます。
上記のすべては、各テーブルにかなりの量の行がある場合に注意されます(公平には、CPU処理やキャッシュのRAMしきい値を超えるものを意味します)。
答えはそれです。 INまたはEXISTS内に複雑なクエリを記述できますが、経験則として、個別値の限られたセットでINを使用し、多数の個別値を持つ行が多い場合はEXISTSを使用するようにしてください。
トリックは、スキャンする行の数を制限することです。
よろしく、
MarianoC
INを介してEXISTSを使用します。以下のリンクを参照してください。
EXISTS
を最適化するには、非常にリテラルにします。そこにある必要がありますが、実際には相関サブクエリから返されるデータは必要ありません。ブール条件を評価しているだけです。
そう:
WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
相関サブクエリはRBAR
であるため、最初の結果ヒットにより条件が真になり、それ以上処理されません。
ここには多くの誤解を招く答えがあります。これには、非常に支持されたものも含まれます(ただし、彼らのopは害を意味するとは思わないが)。 短い答えは:これらは同じです。
(T-)SQL言語には多くのキーワードがありますが、最終的に、ハードウェアで実際に発生するのは、実行クエリプランに見られる操作だけです。
[NOT] IN
および[NOT] EXISTS
を呼び出すときに行うリレーショナル(数学理論)操作は、準結合(NOT
を使用する場合の反結合)です。対応するsql-server操作が同じ名前を持っていることは偶然ではありません。 IN
またはEXISTS
に言及する操作はどこにもありません 反)準結合のみ。したがって、論理的に同等なIN
とEXISTS
の選択がパフォーマンスに影響を与える可能性はありません。結果を取得するための操作。
例:
クエリ1(---(plan )
select * from dt where dt.customer in (select c.code from customer c where c.active=0)
クエリ2( plan )
select * from dt where exists (select 1 from customer c where c.code=dt.customer and c.active=0)