Saat ini saya sedang mencoba mencari tahu bagaimana SQL Server mengevaluasi kardinalitas kisaran predikat yang sebagian mencakup langkah histogram.
Di Internet, pada nilai kardinalitas-estimasi-untuk-dan-untuk-langkah-statistik- saya menemukan pertanyaan serupa dan Paul White memberikan jawaban yang agak menarik.
Menurut jawaban Paul, rumus untuk memperkirakan kardinalitas untuk predikat> = dan> (dalam hal ini, saya hanya tertarik pada model estimator Cardinality minimal 120) adalah sebagai berikut:
Untuk>:
Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * (F * (DISTINCT_RANGE_ROWS - 1)))
Untuk> =:
Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))
Saya menguji aplikasi formula ini pada tabel [Produksi]. [TransactionHistory] dari database AdventureWorks2014 berdasarkan pada predikat kisaran menggunakan kolom TransactionDate dan rentang waktu antara '20140614' dan '20140618'.
Statistik untuk langkah histogram rentang ini adalah sebagai berikut:
Menurut rumus, saya menghitung kardinalitas untuk kueri berikut:
SELECT COUNT(1)
FROM [AdventureWorks2014].[Production].[TransactionHistory]
WHERE [TransactionDate] BETWEEN '20140615 00:00:00.000' AND '20140616 00:00:00.000'
Perhitungan dilakukan dengan menggunakan kode berikut:
DECLARE @predStart DATETIME = '20140615 00:00:00.000'
DECLARE @predEnd DATETIME = '20140616 00:00:00.000'
DECLARE @stepStart DATETIME = '20140614 00:00:00.000'
DECLARE @stepEnd DATETIME = '20140618 00:00:00.000'
DECLARE @predRange FLOAT = DATEDIFF(ms, @predStart, @predEnd)
DECLARE @stepRange FLOAT = DATEDIFF(ms, @stepStart, @stepEnd)
DECLARE @F FLOAT = @predRange / @stepRange;
DECLARE @avg_range_rows FLOAT = 100.3333
DECLARE @distinct_range_rows INT = 3
DECLARE @EQ_ROWS INT = 0
SELECT @F AS 'F'
--for new cardinality estimator
SELECT @EQ_ROWS + @avg_range_rows * (@F * (@distinct_range_rows - 1) + 1) AS [new_card]
Setelah menghitung, saya mendapat hasil sebagai berikut:
Menurut rumus, ternyata 150,5, tetapi pengoptimal memperkirakan predikat pada 225,75 baris, dan jika Anda mengubah batas atas predikat menjadi '20140617', pengoptimal akan mengevaluasi 250.833 baris, sementara menggunakan rumus kami hanya mendapatkan 200.6666 baris.
Tolong beritahu saya, bagaimana Cardinality Estimator mengevaluasi dalam kasus ini, mungkin saya membuat kesalahan di suatu tempat dalam pemahaman saya tentang formula yang dikutip?