Cơ chế đằng sau khả năng truyền tải của việc đúc cho đến nay được gọi là tìm kiếm động .
SQL Server gọi một hàm nội bộ GetRangeThroughConvert
để bắt đầu và kết thúc phạm vi.
Hơi ngạc nhiên khi đây không phải là phạm vi tương tự như các giá trị theo nghĩa đen của bạn.
Tạo một bảng với một hàng trên mỗi trang và 1440 hàng mỗi ngày
CREATE TABLE T
(
DateTimeCol DATETIME PRIMARY KEY,
Filler CHAR(8000) DEFAULT 'X'
);
WITH Nums(Num)
AS (SELECT number
FROM spt_values
WHERE type = 'P'
AND number BETWEEN 1 AND 1440),
Dates(Date)
AS (SELECT {d '2012-12-30'} UNION ALL
SELECT {d '2012-12-31'} UNION ALL
SELECT {d '2013-01-01'} UNION ALL
SELECT {d '2013-01-02'} UNION ALL
SELECT {d '2013-01-03'})
INSERT INTO T
(DateTimeCol)
SELECT DISTINCT DATEADD(MINUTE, Num, Date)
FROM Nums,
Dates
Sau đó chạy
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
SELECT *
FROM T
WHERE DateTimeCol >= '20130101'
AND DateTimeCol < '20130102'
SELECT *
FROM T
WHERE CAST(DateTimeCol AS DATE) = '20130101';
Truy vấn đầu tiên đã 1443
đọc và truy vấn thứ hai 2883
để nó đọc toàn bộ một ngày sau đó loại bỏ nó theo một vị từ còn lại.
Kế hoạch cho thấy vị ngữ tìm kiếm là
Seek Keys[1]: Start: DateTimeCol > Scalar Operator([Expr1006]),
End: DateTimeCol < Scalar Operator([Expr1007])
Vì vậy, thay vì >= '20130101' ... < '20130102'
nó đọc > '20121231' ... < '20130102'
sau đó loại bỏ tất cả các 2012-12-31
hàng.
Một nhược điểm khác của việc dựa vào nó là các ước tính về số lượng thẻ có thể không chính xác như với truy vấn phạm vi truyền thống. Điều này có thể được nhìn thấy trong một phiên bản sửa đổi của SQL Fiddle của bạn .
Tất cả 100 hàng trong bảng hiện khớp với vị từ (với thời gian cách nhau 1 phút tất cả trong cùng một ngày).
Truy vấn thứ hai (phạm vi) ước tính chính xác rằng 100 sẽ khớp và sử dụng quét chỉ mục theo cụm. Các CAST( AS DATE)
truy vấn sai ước tính rằng chỉ có một hàng sẽ phù hợp và tạo ra một kế hoạch với tra cứu chủ chốt.
Các số liệu thống kê không được bỏ qua hoàn toàn. Nếu tất cả các hàng trong bảng có cùng một vị trí datetime
và nó khớp với vị từ (ví dụ 20130101 00:00:00
hoặc 20130101 01:00:00
) thì kế hoạch hiển thị quét chỉ mục theo cụm với ước tính 31.6228 hàng.
100 ^ 0.75 = 31.6228
Vì vậy, trong trường hợp đó, nó xuất hiện ước tính được lấy từ công thức ở đây .
Nếu tất cả các hàng trong bảng đều giống nhau datetime
và nó không khớp với vị từ (ví dụ 20130102 01:00:00
) thì nó sẽ rơi trở lại số hàng ước tính là 1 và kế hoạch có tra cứu.
Đối với các trường hợp trong đó bảng có nhiều hơn một DISTINCT
giá trị, các hàng ước tính dường như giống như khi truy vấn đang tìm kiếm chính xác 20130101 00:00:00
.
Nếu biểu đồ thống kê xảy ra có một bước tại 2013-01-01 00:00:00.000
đó thì ước tính sẽ được dựa trên EQ_ROWS
(tức là không tính đến các thời điểm khác vào ngày đó). Mặt khác, nếu không có bước nào thì có vẻ như nó sử dụng AVG_RANGE_ROWS
từ các bước xung quanh.
Vì datetime
có độ chính xác xấp xỉ 3ms trong nhiều hệ thống, sẽ có rất ít giá trị trùng lặp thực tế và con số này sẽ là 1.