SQL Server 2014 COUNT (DISTINCT x) mengabaikan vektor kepadatan statistik untuk kolom x

15

Untuk COUNT(DISTINCT)yang memiliki ~ 1 miliar nilai berbeda, saya mendapatkan paket permintaan dengan agregat hash yang diperkirakan hanya ~ 3 juta baris.

Mengapa ini terjadi? SQL Server 2012 menghasilkan estimasi yang baik, jadi apakah ini bug di SQL Server 2014 yang harus saya laporkan pada Connect?

Kueri dan taksiran yang buruk

-- Actual rows: 1,011,719,166
-- SQL 2012 estimated rows: 1,079,130,000 (106% of actual)
-- SQL 2014 estimated rows: 2,980,240 (0.29% of actual)
SELECT COUNT(DISTINCT factCol5)
FROM BigFactTable
OPTION (RECOMPILE, QUERYTRACEON 9481) -- Include this line to use SQL 2012 CE

-- Stats for the factCol5 column show that there are ~1 billion distinct values
-- This is a good estimate, and it appears to be what the SQL 2012 CE uses
DBCC SHOW_STATISTICS (BigFactTable, _WA_Sys_00000005_24927208)
--All density   Average Length  Columns
--9.266754E-10  8               factCol5
SELECT 1 / 9.266754E-10
-- 1079126520.46229

Paket kueri

masukkan deskripsi gambar di sini

Skrip lengkap

Berikut adalah repro penuh situasi menggunakan hanya statistik statistik .

Apa yang saya coba sejauh ini

Saya menggali statistik untuk kolom yang relevan dan menemukan bahwa vektor kepadatan menunjukkan sekitar ~ 1,1 miliar nilai yang berbeda. SQL Server 2012 menggunakan estimasi ini dan menghasilkan rencana yang baik. SQL Server 2014, secara mengejutkan, tampaknya mengabaikan estimasi yang sangat akurat yang disediakan oleh statistik dan sebagai gantinya menggunakan estimasi yang jauh lebih rendah. Ini menghasilkan rencana yang jauh lebih lambat yang hampir tidak mencadangkan cukup memori dan tumpah ke tempdb.

Saya mencoba melacak bendera 4199, tetapi itu tidak memperbaiki situasi. Terakhir, saya mencoba menggali informasi pengoptimal melalui kombinasi tanda jejak (3604, 8606, 8607, 8608, 8612), seperti yang ditunjukkan pada paruh kedua artikel ini . Namun, saya tidak dapat melihat informasi yang menjelaskan perkiraan buruk sampai muncul di pohon hasil akhir.

Hubungkan masalah

Berdasarkan jawaban atas pertanyaan ini, saya juga telah mengajukan ini sebagai masalah di Connect

Geoff Patterson
sumber

Jawaban:

14

Cara estimasi kardinalitas diturunkan tentu tampak kontra-intuitif bagi saya. Penghitungan hitungan yang berbeda (dapat dilihat dengan Peristiwa Diperpanjang atau jejak bendera 2363 dan 3604) adalah:

Derivasi statistik

Perhatikan tutupnya. Logika umum ini tampaknya sangat masuk akal (tidak mungkin ada nilai yang lebih berbeda), tetapi batas diterapkan statistik multi-kolom sampel :

DBCC SHOW_STATISTICS 
    (BigFactTable, [PK_BigFactTable])
WITH
    STAT_HEADER, 
    DENSITY_VECTOR;

Statistik PK

Itu menunjukkan 2.980.235 baris sampel dari 3.439.431.721 dengan vektor kepadatan pada tingkat Col5 dari 3.35544E-07. Kebalikan dari itu memberikan sejumlah nilai yang berbeda dari 2.980.235 dibulatkan menggunakan matematika nyata menjadi 2.980.240.

Sekarang pertanyaannya adalah, diberikan statistik sampel, asumsi apa yang harus dibuat oleh model tentang jumlah nilai yang berbeda. Saya mengharapkannya untuk memperkirakan, tetapi itu tidak dilakukan, dan mungkin dengan sengaja.

Lebih intuitif, saya akan berharap bahwa alih-alih menggunakan statistik multi-kolom, itu akan melihat kepadatan pada Col5 (tetapi tidak):

DBCC SHOW_STATISTICS 
    (BigFactTable, [_WA_Sys_00000005_24927208])
WITH
    STAT_HEADER, 
    DENSITY_VECTOR;

Statistik Col5

Di sini densitasnya adalah 9.266754E-10, kebalikannya adalah 1.079.126.528 .

Salah satu solusi yang jelas untuk saat ini adalah memperbarui statistik multi-kolom dengan pemindaian penuh. Yang lainnya adalah menggunakan penduga kardinalitas asli.

Item Hubungkan yang Anda buka, SQL 2014 sampel statistik multi-kolom mengesampingkan statistik satu kolom lebih akurat untuk kolom tidak terkemuka , ditandai Tetap untuk SQL Server 2017.

Paul White Reinstate Monica
sumber