Thuật toán đằng sau toán tử EXCEPT là gì?


10

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ì? 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?

David Lozinksi đã thực hiện một nghiên cứu, SQL: Cách nhanh nhất để chèn các bản ghi mới trong đó không tồn tại. Ông đã chỉ ra Ngoại trừ câu lệnh là nhanh nhất cho các hàng số lượng lớn; buộc chặt vào kết quả của chúng tôi dưới đây.

Giả định: Tôi nghĩ rằng Tham gia trái sẽ nhanh nhất, vì nó chỉ so sánh 1 cột, Ngoại trừ sẽ mất nhiều thời gian nhất, vì nó phải so sánh Tất cả các cột.
Với những kết quả này, bây giờ suy nghĩ của chúng ta là Ngoại trừ tự động và bên trong có băm của mỗi hàng không? Tôi đã xem xét Ngoại trừ kế hoạch thực hiện và nó sử dụng một số hàm băm.

Bối cảnh: Nhóm chúng tôi đã so sánh hai bảng heap. Bảng A Hàng không thuộc Bảng B, được chèn vào Bảng B.

Các bảng heap (từ hệ thống tệp văn bản cũ) không có khóa chính / hướng dẫn / định danh. Một số bảng có các hàng trùng lặp, vì vậy chúng tôi đã tìm thấy Hash của mỗi hàng và xóa các trùng lặp và tạo các định danh khóa chính.

1) Trước tiên, chúng tôi đã chạy một câu lệnh ngoại trừ, ngoại trừ (cột băm)

select * from TableA
Except
Select * from TableB,

2) Sau đó, chúng tôi đã chạy so sánh nối trái giữa hai bảng trên HashRowId

select * 
FROM dbo.TableA A
left join dbo.TableB B
    on A.RowHash =  B.RowHash
where B.Hash is null

đáng ngạc nhiên, Ngoại trừ Chèn Chèn là nhanh nhất.

Kết quả thực tế ánh xạ gần với kết quả kiểm tra từ David Lozinksi

nhập mô tả hình ảnh ở đây


1
Điều đó sẽ không luôn luôn như vậy. Tôi tìm thấy kết quả hơi khác nhau để đọc, ví dụ .
Aaron Bertrand

Câu trả lời:


10

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:

tham gia

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 EXCEPTtừ khóa. Ví dụ: các mục sau đây có cùng một kế hoạch truy vấn giống như EXCEPTtruy 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:

nhập mô tả hình ảnh ở đây

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 EXCEPTvà truy vấn mà không có nó. Dưới đây là kết quả cạnh nhau:

nhập mô tả hình ảnh ở đây

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:

nhập mô tả hình ảnh ở đây

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 EXCEPTdẫn đến một so sánh băm nội bộ đặc biệt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.