Tôi tự hỏi tại sao SQL Server đưa ra các ước tính sai trong trường hợp đơn giản như vậy. Có một kịch bản.
CREATE PARTITION FUNCTION PF_Test (int) AS RANGE RIGHT
FOR VALUES (20140801, 20140802, 20140803)
CREATE PARTITION SCHEME PS_Test AS PARTITION PF_Test ALL TO ([Primary])
CREATE TABLE A
(
DateKey int not null,
Type int not null,
constraint PK_A primary key (DateKey, Type) on PS_Test(DateKey)
)
INSERT INTO A (DateKey, Type)
SELECT
DateKey = N1.n + 20140801,
Type = N2.n + 1
FROM dbo.Numbers N1
cross join dbo.Numbers N2
WHERE N1.n BETWEEN 0 AND 2
and N2.n BETWEEN 0 AND 10000 - 1
UPDATE STATISTICS A (PK_A) WITH FULLSCAN, INCREMENTAL = ON
CREATE TABLE B
(
DateKey int not null,
SubType int not null,
Type int not null,
constraint PK_B primary key (DateKey, SubType) on PS_Test(DateKey)
)
INSERT INTO B (DateKey, SubType, Type)
SELECT
DateKey,
SubType = Type * 10000 + N.n,
Type
FROM A
cross join dbo.Numbers N
WHERE N.n BETWEEN 1 AND 10
UPDATE STATISTICS B (PK_B) WITH FULLSCAN, INCREMENTAL = ON
Vì vậy, việc thiết lập khá đơn giản, thống kê được đưa ra và SQL Server có thể đưa ra các ước tính chính xác khi chúng tôi truy vấn một bảng.
select COUNT(*) from A where DateKey = 20140802
--10000
select COUNT(*) from B where DateKey = 20140802
--100000
Nhưng trong ước tính chọn đơn giản này là cách, và tôi không thấy giải thích tại sao.
SELECT a.DateKey, a.Type
FROM A
JOIN B
ON b.DateKey = a.DateKey
AND b.Type = a.Type
WHERE a.DateKey = 20140802
Ngay sau khi ước tính Tìm kiếm chỉ số cụm là 57% so với thực tế! Truy vấn trong thế giới thực thậm chí còn tồi tệ hơn, ước tính là 2% so với thực tế.
Bảng số PS để tái tạo thiết lập
DECLARE @UpperBound INT = 1000000;
;WITH cteN(Number) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id]) - 1
FROM sys.all_columns AS s1
CROSS JOIN sys.all_columns AS s2
)
SELECT n = [Number] INTO dbo.Numbers
FROM cteN WHERE [Number] <= @UpperBound;
CREATE UNIQUE CLUSTERED INDEX CIX_Number ON dbo.Numbers(n)
WITH
(
FILLFACTOR = 100, -- in the event server default has been changed
DATA_COMPRESSION = ROW -- if Enterprise & table large enough to matter
);
PPS Kịch bản tương tự nhưng không phân vùng hoạt động hoàn hảo.