Bugüne kadar dökümün sertliğinin arkasındaki mekanizmaya dinamik arama denir .
SQL Server GetRangeThroughConvert
, aralığın başlangıcını ve sonunu almak için dahili bir işlevi çağırır .
Biraz da şaşırtıcı bir şekilde, bu sizin gerçek değerlerinizle aynı aralıkta değil .
Sayfa başına satır ve günde 1440 satır içeren bir tablo oluşturma
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
Sonra çalışan
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';
İlk sorgu 1443
okudu ve ikincisi 2883
bütün bir ek gün okuyor, ardından artık bir yükleme karşı atıyor.
Plan arama belirleyicisinin olduğunu gösterir
Seek Keys[1]: Start: DateTimeCol > Scalar Operator([Expr1006]),
End: DateTimeCol < Scalar Operator([Expr1007])
Bunun yerine >= '20130101' ... < '20130102'
okur > '20121231' ... < '20130102'
sonra tüm 2012-12-31
satırları atar .
Buna güvenmenin bir başka dezavantajı, kardinalite tahminlerinin geleneksel aralık sorgusu kadar doğru olmamasıdır. Bu, SQL Fiddle’ınızın değiştirilmiş bir sürümünde görülebilir .
Tablodaki 100 satırın tümü artık yüklemeyle eşleşiyor (aynı gün içinde 1 dakika arayla tarihlenen tarihler).
İkinci (aralık) sorgu, 100'ün eşleşeceğini ve kümelenmiş bir dizin taraması kullanacağını doğru olarak tahmin eder. CAST( AS DATE)
Sorgu yanlış tek satır maç olacağını tahmin eder ve anahtar aramalarını bir plan üretir.
İstatistikler tamamen göz ardı edilmiyor. Tablodaki tüm satırlar aynıysa datetime
ve yükleme (örneğin 20130101 00:00:00
veya 20130101 01:00:00
) eşleşiyorsa , plan, tahmini 31.6228 satır içeren kümelenmiş bir dizin taramasını gösterir.
100 ^ 0.75 = 31.6228
Öyleyse, bu durumda tahmin, buradaki formülden elde edilmiştir .
Tablodaki tüm satırlar aynıysa datetime
ve yükleme (örn. 20130102 01:00:00
) Uymuyorsa, o zaman 1 tahmini satır sayısına ve aramaları içeren plana geri döner.
Tablonun birden fazla DISTINCT
değere sahip olduğu durumlar için , tahmin edilen satırlar, sorgu tam olarak aranıyormuş gibi görünüyor 20130101 00:00:00
.
İstatistik histogramının bir adımı 2013-01-01 00:00:00.000
olması durumunda, tahmin esas alınacaktır EQ_ROWS
(yani o tarihteki diğer zamanları hesaba katmamak). Aksi takdirde, hiçbir adım yoksa, AVG_RANGE_ROWS
çevresindeki basamaklardan kullanıyormuş gibi görünür .
Gibi datetime
birçok sistemlerde yaklaşık 3ms bir hassasiyete sahiptir orada çok az gerçek yinelenen değerleri olacak ve bu sayı 1 olacaktır.