SQL Serverのカバーの下でExcept演算子がどのように機能するかの内部アルゴリズムは何ですか?
には特別な内部アルゴリズムがあるとは言えませんEXCEPT。の場合A EXCEPT B、エンジンはAから個別の(必要な場合)タプルを取得し、Bで一致する行を減算します。特別なクエリプラン演算子はありません。区別と減算は、ソートまたは結合で表示される一般的な演算子を介して実装されます。ネストされたループ結合、マージ結合、およびハッシュ結合がすべてサポートされています。これを示すために、1組のヒープに1500万行をスローします。
DROP TABLE IF EXISTS dbo.TABLE_1;
CREATE TABLE dbo.TABLE_1 (
    COL1 BIGINT NULL,
    COL2 BIGINT NULL
);
INSERT INTO dbo.TABLE_1 WITH (TABLOCK)
SELECT TOP (15000000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)), NULL
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
OPTION (MAXDOP 1);
DROP TABLE IF EXISTS dbo.TABLE_2;
CREATE TABLE dbo.TABLE_2 (
    COL1 BIGINT NULL,
    COL2 BIGINT NULL
);
INSERT INTO dbo.TABLE_2 WITH (TABLOCK)
SELECT TOP (15000000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)), NULL
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
OPTION (MAXDOP 1);
オプティマイザは、ソートと結合の実装方法について通常のコストベースの決定を行います。2つのヒープを使用すると、期待どおりにハッシュ結合が得られます。インデックスを追加するか、いずれかのテーブルのデータを変更することで、他の結合タイプを自然に確認できます。以下では、説明のために、ヒントを使用してマージ結合とループ結合を強制しています。

  内部的に各行のハッシュを取得して比較しますか?
いいえ。他の結合と同様に実装されます。1つの違いは、NULLは等しいものとして扱われることです。これは、実行プランで確認できる特別なタイプの比較です<Compare CompareOp="IS">。ただし、EXCEPTキーワードを含まないT-SQLで同じプランを取得できます。たとえば、次のクエリプランEXCEPTは、ハッシュ結合を使用するクエリとまったく同じです。
SELECT t1.*
FROM
(
    SELECT DISTINCT COL1, COL2
    FROM dbo.TABLE_1
) t1
WHERE NOT EXISTS (
    SELECT 1
    FROM dbo.TABLE_2 t2
    WHERE (t1.COL1 = t2.COL1 OR (t1.COL1 IS NULL AND t2.COL1 IS NULL))
    AND (t1.COL2 = t2.COL2 OR (t1.COL2 IS NULL AND t2.COL2 IS NULL))
);
実行プランのXMLを比較しても、エイリアスなどの表面的な違いのみが明らかになります。ハッシュ結合のプローブ残差は行の比較を行います。どちらのクエリでも同じです。

それでも疑問がある場合は、使用可能な最高のサンプルレートでPerfViewを実行して、クエリのあるコールスタックEXCEPTとないクエリのコールスタックを取得しました。結果を並べて次に示します。

本当の違いはありません。プラン内のハッシュが一致するため、参照ハッシュが存在する呼び出しスタックが存在します。自然なマージ結合を取得するためにインデックスを追加すると、呼び出しスタックにハッシュへの参照が表示されなくなります。

発生するハッシュは、ハッシュ一致演算子の実装によるものです。EXCEPT特別な内部ハッシュ比較につながる特別なものはありません。