กลไกที่อยู่เบื้องหลัง sargability หล่อวันที่เรียกว่าแบบไดนามิกแสวงหา
SQL Server เรียกใช้ฟังก์ชันภายในGetRangeThroughConvert
เพื่อรับจุดเริ่มต้นและจุดสิ้นสุดของช่วง
ค่อนข้างน่าประหลาดใจว่านี่ไม่ใช่ช่วงเดียวกันกับค่าที่แท้จริงของคุณ
การสร้างตารางที่มีแถวต่อหน้าและ 1440 แถวต่อวัน
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
จากนั้นก็วิ่ง
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';
ข้อความค้นหาแรก1443
อ่านแล้วและอ่านครั้งที่สอง2883
เพื่อให้อ่านได้ทั้งวันเพิ่มเติม
แผนแสดงการค้นหาคำกริยาคือ
Seek Keys[1]: Start: DateTimeCol > Scalar Operator([Expr1006]),
End: DateTimeCol < Scalar Operator([Expr1007])
ดังนั้นแทนที่จะ>= '20130101' ... < '20130102'
อ่าน> '20121231' ... < '20130102'
แล้วละทิ้ง2012-12-31
แถวทั้งหมด
ข้อเสียอีกประการหนึ่งของการใช้งานก็คือการประมาณค่า cardinality อาจไม่แม่นยำเท่ากับแบบสอบถามแบบดั้งเดิม สิ่งนี้สามารถเห็นได้ในเวอร์ชันที่แก้ไขของSQL Fiddle ของคุณ
ตอนนี้แถวทั้งหมด 100 แถวในตารางตรงกับภาคแสดง (ด้วยชุดข้อมูล 1 นาทีแยกจากกันในวันเดียวกัน)
แบบสอบถาม (ช่วง) ที่สองถูกต้องประมาณว่า 100 จะจับคู่และใช้การสแกนดัชนีแบบคลัสเตอร์ CAST( AS DATE)
แบบสอบถามไม่ถูกต้องประมาณการว่ามีเพียงหนึ่งแถวจะตรงกับแผนและผลิตด้วยการค้นหาคีย์
สถิติจะไม่ถูกละเว้นอย่างสมบูรณ์ หากแถวทั้งหมดในตารางมีค่าเท่ากันdatetime
และตรงกับเพรดิเคต (เช่น20130101 00:00:00
หรือ20130101 01:00:00
) แผนจะแสดงการสแกนดัชนีแบบคลัสเตอร์ด้วยแถว 31.6228 โดยประมาณ
100 ^ 0.75 = 31.6228
ดังนั้นในกรณีที่ปรากฏว่าการประมาณการดังกล่าวได้มาจากสูตรที่นี่
หากแถวทั้งหมดในตารางมีค่าเท่ากันdatetime
และไม่ตรงกับเพรดิเคต (เช่น20130102 01:00:00
) แถวนั้นจะกลับไปที่จำนวนแถวโดยประมาณที่ 1 และแผนการที่มีการค้นหา
สำหรับกรณีที่ตารางมีมากกว่าหนึ่งมูลค่าประมาณแถวที่ดูเหมือนว่าจะเป็นเช่นเดียวกับถ้าแบบสอบถามกำลังมองหาว่าDISTINCT
20130101 00:00:00
หากฮิสโตแกรมสถิติเกิดขึ้นมีขั้นตอนในตอน2013-01-01 00:00:00.000
นั้นการประมาณจะขึ้นอยู่กับEQ_ROWS
(เช่นไม่คำนึงถึงเวลาอื่นในวันนั้น) มิฉะนั้นหากไม่มีขั้นตอนใด ๆ ดูเหมือนว่าจะใช้AVG_RANGE_ROWS
จากขั้นตอนโดยรอบ
เนื่องจากdatetime
มีความแม่นยำประมาณ 3 มิลลิวินาทีในหลาย ๆ ระบบจะมีค่าซ้ำกันน้อยมากและจำนวนนี้จะเป็น 1