SQL Serverの使用2014:TSQL演算子とINNER JOIN
次の文とパフォーマンスに違いはありますか?あなたの特定の例では
DELETE FROM MyTable where PKID IN (SELECT PKID FROM @TmpTableVar)
と
DELETE FROM MyTable INNER JOIN @TmpTableVar t ON MyTable.PKID = t.PKID
SQL Serverの使用2014:TSQL演算子とINNER JOIN
次の文とパフォーマンスに違いはありますか?あなたの特定の例では
DELETE FROM MyTable where PKID IN (SELECT PKID FROM @TmpTableVar)
と
DELETE FROM MyTable INNER JOIN @TmpTableVar t ON MyTable.PKID = t.PKID
実行計画は、(おそらく)同じになります。
しかし、同じ実行計画を持つということは、このステートメントに対して実行可能な最良の実行計画であるとは限りません。
私があなたの両方の質問に見る問題はTable Variable
の使用です。
SQL Serverは、常にテーブル変数に1行しかないとみなします。 SQL Server 2014以降のバージョンでのみ、この仮定は100行に変更されています。
このように多くの行があっても、テーブル変数SQL Serverは常に@TmpTableVar
に1つの行があるとみなします。
あなたは、SQL ServerのにTemporary table
でそれを置き換えることにより、そのテーブルに存在しますどのように多くの行と、それはあなたがまた、インデックスを作成することができ、あなたのテーブル変数でPK_ID
柱であるためのより良いアイデアを与えるために少しコードを変更することができますそのテーブルでは、このクエリのための最良の実行計画を考え出すためにSQL Serverに最適な機会を与えます。オペレータは
SELECT PKID INTO #Temp
FROM @TmpTableVar
-- Create some index on the temp table here .....
DELETE FROM MyTable
WHERE EXISTS (SELECT 1
FROM #Temp t
WHERE MyTable.PKID = t.PKID)
注
それがテーブル変数の主キー列であるため、正常に動作します。 NULL演算子をNULL値の列で使用した場合、結果は驚くかもしれません.IN演算子は、検査対象の列にNULL値が見つかるとすぐにすべての梨の形をとります。
私は個人的にはこのようなクエリでExists演算子を使用しますが、内部結合も可能です。
ありがとうございます。 @tableVariablesに関係する行の数は内部結合アプローチにも当てはまりますか?私は、インナー・ジョイントをより安全なアプローチとして考えています。 –
SQL Serverでは、そのテーブルに1つの行しか存在しないため、プライマリキー列の結合によって1つの行のみを戻す必要があるため、SQL Serverには効率の悪い実行計画が発生する可能性があります。しかし、これは当てはまりません。したがって、そのようなシナリオでは表変数を使用しないでください。 –
それぞれの実行計画を見てください。この場合、彼らはおそらく同じになるでしょう。 –
実行計画は現在の統計に基づいています。彼らは今日は同じかもしれないが、後で変わる。だから私はもっと広いルールを求めているのです。 –
私はいくつかのテストを行いました、どちらもほぼすべての場合に似ていますhttp://stackoverflow.com/questions/38444729/most-efficient-way-to-select-rows-where-the-id-exists-in-a-second -table/38445287#38445287 – TheGameiswar