Xây dựng một giường thử nghiệm khá đơn giản được thừa nhận trên SQL Server 2012 (11.0.6020) cho phép tôi tạo lại một kế hoạch với hai truy vấn khớp băm được nối thông qua a UNION ALL
. Giường thử nghiệm của tôi không hiển thị ước tính không chính xác mà bạn nhìn thấy. Có lẽ đây là một vấn đề SQL Server 2014 CE.
Tôi nhận được ước tính 133.785 hàng cho một truy vấn thực sự trả về 280 hàng, tuy nhiên đó là điều được mong đợi vì chúng ta sẽ thấy tiếp theo:
IF OBJECT_ID('dbo.Union1') IS NOT NULL
DROP TABLE dbo.Union1;
CREATE TABLE dbo.Union1
(
Union1_ID INT NOT NULL
CONSTRAINT PK_Union1
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, Union1_Text VARCHAR(255) NOT NULL
, Union1_ObjectID INT NOT NULL
);
IF OBJECT_ID('dbo.Union2') IS NOT NULL
DROP TABLE dbo.Union2;
CREATE TABLE dbo.Union2
(
Union2_ID INT NOT NULL
CONSTRAINT PK_Union2
PRIMARY KEY CLUSTERED
IDENTITY(2,2)
, Union2_Text VARCHAR(255) NOT NULL
, Union2_ObjectID INT NOT NULL
);
INSERT INTO dbo.Union1 (Union1_Text, Union1_ObjectID)
SELECT o.name, o.object_id
FROM sys.objects o;
INSERT INTO dbo.Union2 (Union2_Text, Union2_ObjectID)
SELECT o.name, o.object_id
FROM sys.objects o;
GO
SELECT *
FROM dbo.Union1 u1
INNER HASH JOIN sys.objects o ON u1.Union1_ObjectID = o.object_id
UNION ALL
SELECT *
FROM dbo.Union2 u2
INNER HASH JOIN sys.objects o ON u2.Union2_ObjectID = o.object_id;
Tôi nghĩ lý do là xung quanh việc thiếu số liệu thống kê cho hai kết quả tham gia được UNIONed. SQL Server cần đưa ra những phỏng đoán có giáo dục trong hầu hết các trường hợp xung quanh tính chọn lọc của các cột khi phải đối mặt với việc thiếu số liệu thống kê.
Joe Sack có một bài đọc thú vị về điều đó ở đây .
Đối với a UNION ALL
, thật an toàn khi nói rằng chúng ta sẽ thấy chính xác tổng số hàng được trả về bởi mỗi thành phần của liên minh, tuy nhiên vì SQL Server đang sử dụng ước tính hàng cho hai thành phần của UNION ALL
, chúng tôi thấy nó thêm tổng số hàng ước tính từ cả hai các truy vấn để đưa ra ước tính cho toán tử ghép.
Trong ví dụ của tôi ở trên, số lượng hàng ước tính cho mỗi phần của UNION ALL
là 66,8927, khi tổng của nó bằng 133,785, chúng ta thấy số lượng hàng ước tính cho toán tử ghép.
Kế hoạch thực hiện thực tế cho truy vấn công đoàn ở trên trông giống như:
Bạn có thể thấy số lượng hàng "ước tính" so với "thực tế". Trong trường hợp của tôi, việc thêm số lượng hàng "ước tính" được trả về bởi hai toán tử khớp băm chính xác bằng với số lượng được hiển thị bởi toán tử ghép.
Tôi sẽ cố gắng để có được đầu ra từ dấu vết 2363, v.v. như khuyến nghị trong bài đăng của Paul White mà bạn thể hiện trong câu hỏi của mình. Thay phiên, bạn có thể thử sử dụng OPTION (QUERYTRACEON 9481)
trong truy vấn để trở lại phiên bản 70 CE để xem điều đó có "khắc phục" sự cố không.