Đây là một lỗi trong SQL Server (bao gồm từ 2008 đến 2014).
Báo cáo lỗi của tôi là ở đây .
Điều kiện lọc được đẩy xuống toán tử quét dưới dạng một biến vị ngữ còn lại, nhưng bộ nhớ được cấp cho loại được tính toán sai dựa trên ước tính số lượng thẻ lọc trước .
Để minh họa vấn đề, chúng ta có thể sử dụng cờ theo dõi (không có giấy tờ và không được hỗ trợ) 9130 để ngăn Bộ lọc không bị đẩy xuống toán tử quét . Bộ nhớ được cấp cho sắp xếp hiện chính xác dựa trên số lượng ước tính của đầu ra Bộ lọc, chứ không phải quét:
SELECT
T.TID,
T.FilterMe,
T.SortMe,
T.Unused
FROM dbo.Test AS T
WHERE
T.FilterMe = 567
ORDER BY
T.SortMe
OPTION (QUERYTRACEON 9130); -- Not for production systems!
Đối với một hệ thống sản xuất , các bước sẽ cần phải được thực hiện để tránh hình dạng kế hoạch có vấn đề (bộ lọc được đẩy vào quét với một sắp xếp trên cột khác). Một cách để làm điều này là cung cấp một chỉ mục về điều kiện lọc và / hoặc để cung cấp thứ tự sắp xếp cần thiết.
-- Index on the filter condition only
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe
ON dbo.Test (FilterMe);
Với chỉ số này, vị trí cấp bộ nhớ mong muốn cho loại chỉ là 928KB :
Đi xa hơn, chỉ mục sau đây có thể tránh được việc sắp xếp hoàn toàn ( cấp bộ nhớ bằng 0 ):
-- Provides filtering and sort order
-- nvarchar(max) column deliberately not INCLUDEd
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe_SortMe
ON dbo.Test (FilterMe, SortMe);
Đã kiểm tra và xác nhận lỗi trên các bản dựng sau của SQL Server x64 Developer Edition:
2014 : 12.00.2430 (RTM CU4)
2012 : 11.00.5556 (SP2 CU3)
2008R2 : 10.50.6000 (SP3)
2008 : 10.00.6000 (SP4)
Điều này đã được sửa trong SQL Server 2016 Gói dịch vụ 1 . Các ghi chú phát hành bao gồm:
Số lỗi VSTS 8024987 Quét
bảng và quét chỉ mục với vị từ đẩy xuống có xu hướng đánh giá quá cao việc cấp bộ nhớ cho toán tử cha.
Đã kiểm tra và xác nhận cố định trên:
Microsoft SQL Server 2016 (SP1) - 13.0.4001.0 (X64) Developer Edition
Microsoft SQL Server 2014 (SP2-CU3) 12.0.5538.0 (X64) Developer Edition
Cả hai mô hình CE.