Các bài kiểm tra này (cơ sở dữ liệu AdventureWorks2008R2) cho thấy điều gì sẽ xảy ra:
SET NOCOUNT ON;
SET STATISTICS IO ON;
PRINT 'Test #1';
SELECT p.BusinessEntityID, p.LastName
FROM Person.Person p
WHERE p.LastName LIKE '%be%';
PRINT 'Test #2';
DECLARE @Pattern NVARCHAR(50);
SET @Pattern=N'%be%';
SELECT p.BusinessEntityID, p.LastName
FROM Person.Person p
WHERE p.LastName LIKE @Pattern;
SET STATISTICS IO OFF;
SET NOCOUNT OFF;
Kết quả:
Test #1
Table 'Person'. Scan count 1, logical reads 106
Test #2
Table 'Person'. Scan count 1, logical reads 106
Kết quả từ SET STATISTICS IO
cho thấy LIO đều giống nhau .Nhưng các kế hoạch thực hiện khá khác nhau:
Trong thử nghiệm đầu tiên, SQL Server sử dụng Index Scan
rõ ràng nhưng trong thử nghiệm thứ hai, SQL Server sử dụng Index Seek
là một Index Seek - range scan
. Trong trường hợp cuối cùng, SQL Server sử dụng Compute Scalar
toán tử để tạo các giá trị này
[Expr1005] = Scalar Operator(LikeRangeStart([@Pattern])),
[Expr1006] = Scalar Operator(LikeRangeEnd([@Pattern])),
[Expr1007] = Scalar Operator(LikeRangeInfo([@Pattern]))
và Index Seek
toán tử sử dụng Seek Predicate
(được tối ưu hóa) cho range scan
(LastName > LikeRangeStart AND LastName < LikeRangeEnd
) cộng với một Predicate
khác chưa được tối ưu hóa (LastName LIKE @pattern
).
Câu trả lời của tôi:đây không phải là Index Seek
"thực" . Đó là một Index Seek - range scan
trong trường hợp này, có cùng hiệu suất như Index Scan
.
Ngoài ra, vui lòng xem sự khác biệt giữa Index Seek
và Index Scan
(cuộc tranh luận tương tự): Vậy… nó là Tìm kiếm hay Quét?
.
Chỉnh sửa 1: Kế hoạch thực thi cho OPTION(RECOMPILE)
(vui lòng xem khuyến nghị của Aaron) cũng cho thấy Index Scan
(thay vì Index Seek
):