Mekanisme di balik sargability casting hingga saat ini disebut pencarian dinamis .
SQL Server memanggil fungsi internal GetRangeThroughConvert
untuk mendapatkan awal dan akhir kisaran.
Agak mengherankan ini tidak kisaran yang sama dengan nilai literal Anda.
Membuat tabel dengan baris per halaman dan 1440 baris per hari
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
Lalu berlari
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';
Kueri pertama telah 1443
membaca dan yang kedua 2883
sehingga membaca seluruh hari tambahan kemudian membuangnya terhadap predikat residual.
Rencana tersebut menunjukkan predikat pencarian tersebut
Seek Keys[1]: Start: DateTimeCol > Scalar Operator([Expr1006]),
End: DateTimeCol < Scalar Operator([Expr1007])
Jadi alih-alih >= '20130101' ... < '20130102'
membacanya, > '20121231' ... < '20130102'
buang semua 2012-12-31
baris.
Kerugian lain dari mengandalkannya adalah bahwa perkiraan kardinalitas mungkin tidak seakurat dengan kueri rentang tradisional. Ini dapat dilihat dalam versi amandemen SQL Fiddle Anda .
Semua 100 baris dalam tabel sekarang cocok dengan predikat (dengan datetimes terpisah 1 menit pada hari yang sama).
Kueri (rentang) kedua dengan benar memperkirakan bahwa 100 akan cocok dan menggunakan pemindaian indeks berkerumun. The CAST( AS DATE)
permintaan salah memperkirakan bahwa hanya satu baris akan cocok dan menghasilkan rencana dengan pencarian kunci.
Statistik tidak diabaikan sepenuhnya. Jika semua baris dalam tabel memiliki yang sama datetime
dan cocok dengan predikat (misalnya 20130101 00:00:00
atau 20130101 01:00:00
) maka rencana menunjukkan pemindaian indeks berkerumun dengan perkiraan 31,6228 baris.
100 ^ 0.75 = 31.6228
Jadi dalam hal ini tampaknya perkiraan tersebut berasal dari rumus di sini .
Jika semua baris dalam tabel memiliki yang sama datetime
dan tidak cocok dengan predikat (mis. 20130102 01:00:00
) Maka jatuh kembali ke perkiraan jumlah baris 1 dan rencana dengan pencarian.
Untuk kasus di mana tabel memiliki lebih dari satu DISTINCT
nilai, baris yang diestimasi tampaknya sama seperti jika kueri mencari dengan tepat 20130101 00:00:00
.
Jika histogram statistik memiliki langkah pada 2013-01-01 00:00:00.000
maka estimasi akan didasarkan pada EQ_ROWS
(yaitu tidak memperhitungkan waktu lain pada tanggal itu). Kalau tidak, jika tidak ada langkah sepertinya menggunakan AVG_RANGE_ROWS
dari langkah-langkah sekitarnya.
Karena datetime
memiliki presisi sekitar 3ms dalam banyak sistem akan ada sangat sedikit nilai duplikat aktual dan angka ini akan menjadi 1.