Các kế hoạch truy vấn với các bộ lọc bitmap đôi khi có thể khó đọc. Từ bài viết BOL cho các luồng phân vùng (nhấn mạnh của tôi):
Toán tử Repartition Streams tiêu thụ nhiều luồng và tạo ra nhiều luồng bản ghi. Các nội dung và định dạng hồ sơ không được thay đổi. Nếu trình tối ưu hóa truy vấn sử dụng bộ lọc bitmap, số lượng hàng trong luồng đầu ra sẽ giảm.
Ngoài ra, một bài viết về bộ lọc bitmap cũng hữu ích:
Khi phân tích một kế hoạch thực hiện có chứa lọc bitmap, điều quan trọng là phải hiểu cách dữ liệu chảy qua kế hoạch và nơi áp dụng lọc. Bộ lọc bitmap và bitmap được tối ưu hóa được tạo ở phía đầu vào bản dựng (bảng thứ nguyên) của phép nối băm; tuy nhiên, quá trình lọc thực tế thường được thực hiện trong toán tử Parallelism, nằm ở phía đầu vào của đầu dò (bảng thực tế) của phép nối băm. Tuy nhiên, khi bộ lọc bitmap dựa trên một cột số nguyên, bộ lọc có thể được áp dụng trực tiếp vào bảng ban đầu hoặc hoạt động quét chỉ mục thay vì toán tử Parallelism. Kỹ thuật này được gọi là tối ưu hóa liên tiếp.
Tôi tin rằng đó là những gì bạn đang quan sát với truy vấn của bạn. Có thể đưa ra một bản demo tương đối đơn giản để hiển thị toán tử luồng phân vùng lại làm giảm ước tính cardinality, ngay cả khi toán tử bitmap IN_ROW
chống lại bảng thực tế. Chuẩn bị dữ liệu:
create table outer_tbl (ID BIGINT NOT NULL);
INSERT INTO outer_tbl WITH (TABLOCK)
SELECT TOP (1000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values;
create table inner_tbl_1 (ID BIGINT NULL);
create table inner_tbl_2 (ID BIGINT NULL);
INSERT INTO inner_tbl_1 WITH (TABLOCK)
SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
INSERT INTO inner_tbl_2 WITH (TABLOCK)
SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
Đây là một truy vấn mà bạn không nên chạy:
SELECT *
FROM outer_tbl o
INNER JOIN inner_tbl_1 i ON o.ID = i.ID
INNER JOIN inner_tbl_2 i2 ON o.ID = i2.ID
OPTION (HASH JOIN, QUERYTRACEON 9481, QUERYTRACEON 8649);
Tôi đã tải lên kế hoạch . Hãy nhìn vào các nhà điều hành gần inner_tbl_2
:
Bạn cũng có thể thấy thử nghiệm thứ hai trong Hash Joins trên Nullable Cột của Paul White hữu ích.
Có một số mâu thuẫn trong cách áp dụng giảm hàng. Tôi chỉ có thể nhìn thấy nó trong một kế hoạch với ít nhất ba bảng. Tuy nhiên, việc giảm các hàng dự kiến có vẻ hợp lý với phân phối dữ liệu phù hợp. Giả sử rằng cột đã tham gia trong bảng thực tế có nhiều giá trị lặp lại không có trong bảng thứ nguyên. Bộ lọc bitmap có thể loại bỏ các hàng đó trước khi chúng tham gia. Đối với truy vấn của bạn, ước tính được giảm xuống còn 1. Cách các hàng được phân phối giữa hàm băm cung cấp một gợi ý hay:
Dựa vào đó tôi nghi ngờ rằng bạn có rất nhiều giá trị lặp lại cho Object1.Column21
cột. Nếu các cột lặp lại xảy ra không có trong biểu đồ thống kê Object4.Column19
thì SQL Server có thể nhận được ước tính cardinality rất sai.
Tôi nghĩ rằng bạn nên quan tâm đến việc có thể cải thiện hiệu năng của truy vấn. Tất nhiên, nếu truy vấn đáp ứng yêu cầu về thời gian đáp ứng hoặc SLA thì có thể không cần điều tra thêm. Tuy nhiên, nếu bạn muốn điều tra thêm, có một số điều bạn có thể làm (ngoài việc cập nhật số liệu thống kê) để có ý tưởng về việc trình tối ưu hóa truy vấn sẽ chọn một kế hoạch tốt hơn nếu có thông tin tốt hơn. Bạn có thể đặt kết quả của phép nối giữa Database1.Schema1.Object10
và Database1.Schema1.Object11
vào một bảng tạm thời và xem liệu bạn có tiếp tục nhận được các phép nối vòng lặp lồng nhau không. Bạn có thể thay đổi tham gia đó thành một LEFT OUTER JOIN
trình tối ưu hóa truy vấn sẽ không làm giảm số lượng hàng tại bước đó. Bạn có thể thêm một MAXDOP 1
gợi ý cho truy vấn của bạn để xem điều gì xảy ra. Bạn đã có thể sử dụngTOP
cùng với một bảng dẫn xuất để buộc tham gia đi cuối cùng, hoặc thậm chí bạn có thể nhận xét tham gia từ truy vấn. Hy vọng rằng những gợi ý này là đủ để bạn bắt đầu.
Liên quan đến mục kết nối trong câu hỏi, rất khó có khả năng nó liên quan đến câu hỏi của bạn. Vấn đề đó không liên quan đến ước tính hàng kém. Nó phải làm với một điều kiện cuộc đua song song khiến quá nhiều hàng được xử lý trong kế hoạch truy vấn phía sau hậu trường. Ở đây có vẻ như truy vấn của bạn không làm thêm bất kỳ công việc nào.