Mengapa SQL Server tidak melakukan histogram statistik kolom majemuk?

10

SQL Server memiliki sesuatu yang disebut "statistik multi-kolom", tetapi bukan itu yang dipikirkan orang.

Mari kita lihat tabel contoh berikut:

CREATE TABLE BadStatistics 
(
    IsArchived BIT NOT NULL,
    Id INT NOT NULL IDENTITY PRIMARY KEY,
    Mystery VARCHAR(200) NOT NULL
);

CREATE NONCLUSTERED INDEX BadIndex 
    ON BadStatistics (IsArchived, Mystery);

Dengan itu, dua statistik sedang dibuat pada dua indeks yang kami miliki:

Statistik untuk BadIndex:

+--------------+----------------+-------------------------+
| All density  | Average Length | Columns                 |
+--------------+----------------+-------------------------+
| 0.5          | 1              | IsArchived              |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 37             | IsArchived, Mystery     |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 41             | IsArchived, Mystery, Id |
+--------------+----------------+-------------------------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 0            | 0          | 24398   | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 216602  | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

Statistik untuk indeks berkerumun:

+--------------+----------------+---------+
| All density  | Average Length | Columns |
+--------------+----------------+---------+
| 4.149378E-06 | 4              | Id      |
+--------------+----------------+---------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 240999       | 240997     | 1       | 240997              | 1              |
+--------------+------------+---------+---------------------+----------------+
| 241000       | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

(Saya telah mengisi tabel dengan data sampel acak di mana sekitar sepersepuluh dari baris tidak diarsipkan. Saya menjalankan pembaruan statistik pemindaian penuh setelah itu.)

Mengapa histogram statistik dua kolom hanya menggunakan satu kolom? Saya tahu bahwa banyak orang telah menulis tentang bahwa itu tidak , tapi apa alasan itu? Dalam hal ini, ini membuat keseluruhan histogram menjadi kurang bermanfaat, karena kolom pertama hanya memiliki dua nilai. Mengapa statistik dibatasi secara sewenang-wenang seperti itu?

Harap dicatat bahwa pertanyaan ini tidak mengacu pada histogram multi-dimensi, yang merupakan binatang yang sama sekali berbeda. Ini tentang histogram satu dimensi dengan dimensi tunggal menjadi tupel yang berisi masing-masing, beberapa kolom.

John
sumber

Jawaban:

8

Latar Belakang

Model SQL Server saat ini hanya menggunakan histogram kolom tunggal dan informasi kepadatan multi-kolom. Histogram kolom tunggal digunakan untuk memperkirakan selektivitas untuk predikat yang sesuai misalnya a = 1atau b > 50. Permintaan dengan beberapa predikat hanya menggabungkan selektivitas individual (dengan asumsi) untuk menghasilkan perkiraan selektivitas keseluruhan.

Sebagai contoh, lihat artikel saya Perkiraan Kardinalitas: Menggabungkan Statistik Kepadatan

Kepadatan multi-kolom selanjutnya menginformasikan model dengan memberikan informasi korelasi yang lemah untuk beberapa predikat kesetaraan dan kardinalitas pengelompokan untuk agregasi.

Statistik yang terkait dengan indeks adalah tambahan oportunistik untuk model itu: Mesin mungkin juga mengumpulkan statistik (biasanya pemindaian penuh) saat sedang membangun indeks. SQL Server secara otomatis membuat histogram kolom terkemuka dan informasi kepadatan untuk kunci lainnya.

Histogram untuk non-terkemuka kolom dalam indeks dapat dibangun pada permintaan secara otomatis oleh prosesor query, atau terlebih dahulu dengan menggunakan sp_createstatsdengan @indexonlypilihan (antara lain).

Histogram multi-kolom

Asumsi yang dibuat ketika menggabungkan statistik satu kolom (seperti di atas) dapat memodelkan realitas data dengan cukup baik. Dalam banyak kasus, opsi yang tersedia (backon eksponensial, independensi, selektivitas minimum) menghasilkan perkiraan yang 'cukup baik'.

Kami juga telah memfilter statistik (dan indeks) sebagai solusi alami untuk indeks kolom utama kardinalitas rendah seperti dalam contoh pertanyaan. Membawa ini ke ekstrim logis membawa kita lebih dekat ke statistik multi-dimensi bahwa pertanyaannya bukan tentang.

Ketika opsi pemodelan yang tersedia tidak dapat memberikan perkiraan yang cocok, histogram statistik multi-kolom memang bisa memberikan perkiraan selektivitas yang lebih baik untuk predikat indeks yang sesuai, dalam beberapa kasus. Ada beberapa kesulitan dalam menggabungkan tipe data yang berbeda dalam kolom yang berbeda, tetapi tidak ada yang dapat diatasi.

Kami juga membutuhkan histogram untuk setiap level kunci indeks (untuk hasil terbaik); jadi untuk indeks pada (a, b, c)itu akan berarti histogram (a, b)dan (a, b, c)selain histogram kolom tunggal saat ini (a)saja.

Mekanisme yang digunakan untuk mendeteksi statistik basi juga perlu dimodifikasi untuk mempertahankan histogram multi-kolom yang terpengaruh. Histogram ini kemungkinan akan dibangun kembali lebih sering daripada statistik satu kolom, hanya karena modifikasi pada lebih banyak kolom memengaruhi mereka.

Semua ini menambah ukuran, kompleksitas, dan overhead pemeliharaan.

Statistik multi-kolom dapat disimulasikan (sampai batas tertentu) menggunakan statistik yang dibuat pada kolom yang dikomputasi dengan hati-hati yang merujuk beberapa kolom. Kueri perlu menyertakan predikat pada kolom yang dihitung (atau pencocokan tekstual yang tepat untuk rumus yang mendasarinya) untuk memanfaatkan statistik itu. Mungkin hanya ada situasi yang sangat terbatas di mana pendekatan ini praktis. Namun demikian, ia memiliki beberapa masalah implementasi yang sama dengan histogram multi-kolom otomatis.

Pada akhirnya, satu-satunya orang yang bisa mengatakan dengan pasti mengapa SQL Server tidak mendukung statistik multi-kolom adalah para desainer itu sendiri. Jika Anda merasa dapat memberikan alasan yang kuat untuk peningkatan produk di bidang ini dengan penerapan yang luas, Anda dapat menyarankannya di Connect atau melalui saluran dukungan normal Anda.

Catatan kaki

Dalam hal ini, ini membuat keseluruhan histogram menjadi kurang bermanfaat, karena kolom pertama hanya memiliki dua nilai

Histogram masih memberikan informasi yang berguna tentang distribusi nilai di kolom terkemuka: Ketika statistik dibangun, ada 24.398 baris IsArchivedyang salah , dan 216.602 baris di mana itu benar .

Selain itu, objek statistik memberitahu kita ada (1 / 0,5) = 2 nilai berbeda untuk IsArchived, (1 / 4.149378E-06) ~ = 241000 nilai berbeda untuk (IsArchived, Mystery)dengan ukuran baris rata-rata 37 byte, dan ada frekuensi yang sama untuk (IsArchived, Mystery, Id)dengan 4 byte tambahan per baris.

Itu semua informasi tujuan umum yang baik, yang dapat dikombinasikan dengan informasi statistik tentang kolom lain untuk menghasilkan perkiraan selektivitas dalam permintaan dengan beberapa predikat (seperti yang disebutkan).

Paul White 9
sumber