Thuật toán bên trong về cách toán tử Ngoại lệ hoạt động dưới vỏ bọc trong SQL Server là gì?
Tôi sẽ không nói rằng có một thuật toán nội bộ đặc biệt cho EXCEPT
. Đối với A EXCEPT B
, công cụ lấy các bộ dữ liệu riêng biệt (nếu cần) từ A và trừ các hàng khớp với B. Không có toán tử kế hoạch truy vấn đặc biệt nào. Sự khác biệt và phép trừ được thực hiện thông qua các toán tử điển hình mà bạn sẽ thấy với một loại hoặc với một phép nối. Tham gia vòng lặp lồng nhau, hợp nhất tham gia và tham gia băm đều được hỗ trợ. Để thể hiện điều này, tôi sẽ ném 15 triệu hàng thành một đống:
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);
Trình tối ưu hóa làm cho nó quyết định dựa trên chi phí thông thường về cách thực hiện sắp xếp và tham gia. Với hai đống tôi nhận được một tham gia băm như mong đợi. Bạn có thể thấy các loại tham gia khác một cách tự nhiên bằng cách thêm chỉ mục hoặc bằng cách thay đổi dữ liệu trong một trong hai bảng. Dưới đây tôi buộc hợp nhất và vòng lặp tham gia với các gợi ý chỉ nhằm mục đích minh họa:
Có phải trong nội bộ lấy một hàm băm của mỗi hàng và so sánh?
Không. Nó được thực hiện như bất kỳ tham gia khác. Một sự khác biệt là NULL được coi là bằng nhau. Đây là một loại so sánh đặc biệt mà bạn có thể thấy trong kế hoạch thực hiện : <Compare CompareOp="IS">
. Tuy nhiên, bạn có thể có cùng một kế hoạch với T-SQL không bao gồm EXCEPT
từ khóa. Ví dụ: các mục sau đây có cùng một kế hoạch truy vấn giống như EXCEPT
truy vấn sử dụng phép nối băm:
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))
);
Khác biệt XML của các kế hoạch thực hiện chỉ cho thấy sự khác biệt bề ngoài xung quanh bí danh và những thứ tương tự. Phần dư thăm dò cho hàm băm tham gia so sánh hàng. Chúng giống nhau cho cả hai truy vấn:
Nếu bạn vẫn còn nghi ngờ, tôi đã chạy PerfView với tỷ lệ mẫu khả dụng cao nhất để có được các ngăn xếp cuộc gọi cho truy vấn EXCEPT
và truy vấn mà không có nó. Dưới đây là kết quả cạnh nhau:
Không có sự khác biệt thực sự. Các ngăn xếp cuộc gọi có băm tham chiếu có mặt vì các kết quả băm trong kế hoạch. Nếu tôi thêm các chỉ mục để có được một phép nối hợp nhất tự nhiên, bạn sẽ không thấy bất kỳ tham chiếu nào để băm trong ngăn xếp cuộc gọi:
Bất kỳ băm nào xảy ra là do việc thực hiện các toán tử khớp băm. Không có gì đặc biệt EXCEPT
dẫn đến một so sánh băm nội bộ đặc biệt.