SQL Server: Ước tính hàng chính xác mà không có biểu đồ?


7

Tôi đang khám phá trình tối ưu hóa trong SQL Server, đặc biệt là biểu đồ và tôi thấy một số kết quả lạ.

Nếu tôi thực hiện truy vấn bên dưới, nơi tôi biết không có biểu đồ trên trường, SQL Server sẽ đưa ra ước tính hàng bằng với kết quả thực tế. Nếu tôi chạy cùng một truy vấn mà tôi sử dụng DECLARE @i NUMERIC(19,2) = 30.0thay vì hằng số WHERE [Rate] < @i, thì ước tính là 94.8như tôi mong đợi cho truy vấn được hiển thị do cơ sở dữ liệu không có số liệu thống kê về trường.

Ước tính truy vấn

Vì vậy, câu hỏi của tôi là tại sao SQL Server xuất ra kết quả chính xác khi nó không có số liệu thống kê về lĩnh vực này?


Khi tắt AUTO_CREATE_STATISTICSnhư được chỉ ra bởi câu trả lời của tôi, tôi gặp một số hành vi kỳ lạ trên các ước tính hàng.

Một ràng buộc tồn tại trên bảng giới hạn [Rate]ở giữa 6.5 - 200.0. Các ước tính thay đổi rất nhiều khi thử nghiệm tùy thuộc vào việc >được sử dụng hay >=cũng như 24.0hoặc 64các truy vấn định dạng trong đó vị từ hiển thị một chuyển đổi ngụ ý sang loại money.

Đối với WHERE [Rate] > 6.5ước tính là 28.44sau đó dừng lại ở mức giá trên 100.

Đối với WHERE [Rate] > 7trường hợp số thập phân được loại trừ, 28.44ước tính sẽ chạy hết cỡ255

Đối với WHERE [Rate] >= 6.5các 28.44ước tính chạy lên đến khoảng 100sau đó thay đổi để 17.7764lên đến 1000trước khi ước tính giảm xuống còn 1.

Vì vậy, dường như không có nhiều sự nhất quán. Có vẻ như SQL Server nhận thức được các ràng buộc dựa trên một số truy vấn tôi đang thử nghiệm, nhưng đôi khi nó cũng bỏ qua sự hiện diện của nó.

Câu trả lời:


13

Đầu tiên, như bạn nhận thấy, SQL Server sẽ tự động tạo số liệu thống kê bị thiếu (nếu có thể) khi biên dịch kế hoạch thực hiện, nếu tùy chọn cơ sở dữ liệu AUTO_CREATE_STATISTICSđược bật.

Khi số liệu thống kê không có sẵn, dự đoán mặc định cho một vị từ bất đẳng thức không xác định là 0,3 (30%). Khi bạn sử dụng một biến cục bộ, giá trị trong biến đó không thể được đánh hơi (trừ khi OPTION (RECOMPILE)cũng được chỉ định). Với số lượng thẻ bảng là 316, ước tính là 0,3 * 316 = 94,8.

Khi bạn sử dụng một chữ không đổi, giá trị được đánh hơi. Nếu không có số liệu thống kê, nó không thể sử dụng giá trị đánh hơi này để kiểm tra biểu đồ như bình thường, nhưng nó có thể đánh giá tác động của nó đối với CHECKràng buộc (một giá trị Tỷ lệ giới hạn trong khoảng từ 6,50 đến 200 đô la).

Nếu giá trị đánh hơi không loại trừ hoàn toàn phạm vi ràng buộc kiểm tra , ước tính dựa trên độ chọn lọc đoán được 0,09 (9%) cho một BETWEENvị từ (từ ràng buộc kiểm tra). 316 * 0,09 = 28,44.

Nếu giá trị đánh hơi hoàn toàn loại trừ phạm vi ràng buộc kiểm tra, ước tính luôn là 1 hàng (công cụ ước tính cardinality (gần như) không bao giờ tạo ra số lượng hàng ước tính nhỏ hơn 1).

Nếu truy vấn đủ đơn giản để đủ điều kiện cho một kế hoạch tầm thường và nó được coi là an toàn cho tham số hóa đơn giản, thì hằng số được thay thế bằng một dấu tham số, ví dụ @1. Điều này xảy ra cho một truy vấn như:

SELECT * 
FROM HumanResources.EmployeePayHistory AS EPH 
WHERE EPH.Rate > $200;

Kế hoạch thực hiện cho thấy ước tính 1 hàng:

Kế hoạch

Và Dự đoán quét hiển thị điểm đánh dấu tham số:

Tính chất

Nếu tham số hóa đơn giản bị ngăn chặn, ví dụ: bằng cách thêm một mệnh đề so sánh hằng số với hằng số:

SELECT * 
FROM HumanResources.EmployeePayHistory AS EPH 
WHERE EPH.Rate > $200
AND 1 = 1;

Nếu không tham số hóa, kế hoạch này không bao giờ có thể được sử dụng lại với một giá trị khác cho tham số, vì vậy trình tối ưu hóa có thể loại bỏ tĩnh truy cập bảng trên cơ sở ràng buộc kiểm tra ngăn chặn mọi hàng được trả về. Kế hoạch bán lại là:

Quét liên tục

Cuối cùng, hãy cẩn thận với các loại. Loại cột Tỷ lệ là tiền , không phải số thập phân . Chuyển đổi có thể ảnh hưởng đến ước tính cardinality theo những cách phức tạp. Chỉ định một nghĩa đen tiền với tiền tố $, hoặc sử dụng một rõ ràng CASThoặc CONVERT.


Các chi tiết nội bộ của ước tính cardinality không được ghi lại công khai (có thể để tránh các câu hỏi và khiếu nại chi tiết hơn bao giờ hết khi mọi thứ thay đổi), nhưng có một loạt các nguồn lực để hỗ trợ bạn trong lĩnh vực này. Chỉ cần nhớ hầu hết điều này là không chính thức và vì vậy không được hỗ trợ bởi bất cứ ai. Một số khía cạnh thực sự nguy hiểm.

Một số chỉ áp dụng cho công cụ ước tính cardinality gốc (trước năm 2014), một số giải thích các nguyên tắc chung áp dụng cho cả hai và một số chỉ áp dụng cho CE "mới". Sau đây không có nghĩa là một danh sách có thẩm quyền hoặc đầy đủ, chỉ là những danh sách xuất hiện trong tâm trí ngay lập tức:


1

Điều tôi nhận thấy là, khi AUTO_CREATE_STATISTICSbật, SQL Server đang âm thầm tính toán biểu đồ trên trường trước khi tôi chạy truy vấn.

Khi tôi AUTO_CREATE_STATISTICStắt và thực hiện cùng một truy vấn, tôi sẽ có được ước tính hợp lý hơn nhiều (vì nó không có số liệu thống kê). Xem bên dưới:

Tự động tạo tắt

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.