Sự khác biệt giữa Vị ngữ tìm kiếm và Vị ngữ


12

Tôi đang cố gắng thực hiện điều chỉnh một truy vấn mà chúng tôi có trong SQL Server 2014 Enterprise.

Tôi đã mở kế hoạch truy vấn thực tế trong SQL Sentry Plan Explorer và tôi có thể thấy trên một nút có Dự báo tìm kiếm và cũng là Vị ngữ

Sự khác biệt giữa Vị ngữ tìm kiếmVị ngữ là gì?

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

Lưu ý: Tôi có thể thấy rằng có rất nhiều vấn đề với nút này (ví dụ: các hàng Ước tính so với thực tế, IO dư), nhưng câu hỏi không liên quan đến bất kỳ vấn đề nào.


3
Vị từ tìm kiếm hỗ trợ với phép nối, chỉ lọc các hàng cũng được tìm thấy trong bảng khác (mà bạn đã xử lý lại). Vị từ (một vị từ còn lại) sau đó loại bỏ các hàng có trạng thái cụ thể là 2.
Aaron Bertrand

5
Rob Farley đã nêu những điều sau đây trong một bình luận ở đây :The Seek Predicate can be used to find the start of the RangeScan and then when to stop, while the Predicate is the "check" that is applied to every row in the Range.
Aaron Bertrand

Câu trả lời:


18

Chúng ta hãy ném một triệu hàng vào một bảng tạm thời cùng với một vài cột:

CREATE TABLE #174860 (
PK INT NOT NULL, 
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (PK)
);

INSERT INTO #174860 WITH (TABLOCK)
SELECT RN
, RN % 1000
, RN % 10000
FROM 
(
    SELECT TOP 1000000 ROW_NUMBER () OVER (ORDER BY (SELECT NULL)) RN
    FROM   master..spt_values v1,
           master..spt_values v2
) t;

CREATE INDEX IX_174860_IX ON #174860 (COL1) INCLUDE (COL2);

Ở đây tôi có một chỉ mục cụm (theo mặc định) trên PKcột. Có một chỉ mục không bao gồm trên COL1đó có một cột chính COL1và bao gồm COL2.

Hãy xem xét các truy vấn sau:

SELECT *
FROM #174860
WHERE PK >= 15000 AND PK < 15005
AND COL2 = 5000;

Ở đây tôi không sử dụng BETWEENvì Aaron Bertrand đang lảng vảng câu hỏi này.

SQL Server nên tối ưu hóa truy vấn đó như thế nào? Chà, tôi biết rằng bộ lọc trên PKsẽ giảm kết quả được đặt thành năm hàng. Máy chủ SQL có thể sử dụng chỉ mục được nhóm để nhảy đến năm hàng đó thay vì đọc qua tất cả hàng triệu hàng trong bảng. Tuy nhiên, chỉ mục cụm chỉ có cột PK là cột chính. Khi hàng được đọc vào bộ nhớ, chúng ta cần áp dụng bộ lọc trên COL2. Ở đây, PKlà một vị ngữ tìm kiếm và COL2là một vị ngữ.

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

Máy chủ SQL tìm thấy năm hàng bằng cách sử dụng vị từ tìm kiếm và tiếp tục giảm năm hàng đó thành một hàng với vị từ thông thường.

Nếu tôi xác định chỉ mục cụm khác nhau:

CREATE TABLE #174860 (
PK INT NOT NULL, 
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (COL2, PK)
);

Và chạy cùng một truy vấn tôi nhận được kết quả khác nhau:

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

Trong trường hợp này, SQL Server có thể tìm kiếm bằng cách sử dụng cả hai cột trong WHEREmệnh đề. Chính xác một hàng được đọc từ bảng bằng các cột chính.

Để biết thêm một ví dụ, hãy xem xét truy vấn này:

SELECT *
FROM #174860
WHERE COL1 = 500
AND COL2 = 3545;

Chỉ mục IX_174860_IX là chỉ mục bao phủ vì nó chứa tất cả các cột cần thiết cho truy vấn. Tuy nhiên, chỉ COL1là một cột quan trọng. SQL Server có thể tìm kiếm với cột đó để tìm 1000 hàng có COL1giá trị khớp . Nó có thể lọc thêm các hàng trên COL2cột để giảm kết quả cuối cùng được đặt thành 0 hàng.

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

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.