Statistik. Apakah histogram multikolom dimungkinkan?

13

Saya memikirkan situasi di mana saya memiliki dua kolom dengan kepadatan tinggi tetapi kolom ini tidak independen.

Definisi

Ini dia definisi dari tabel yang telah saya buat untuk tujuan pengujian.

CREATE TABLE [dbo].[StatsTest](
    [col1] [int] NOT NULL,  --can take values 1 and 2 only
    [col2] [int] NOT NULL,  --can take integer values from 1 to 4 only
    [col3] [int] NOT NULL,  --integer. it has not relevance just to ensure that each row is different
    [col4]  AS ((10)*[col1]+[col2])  --a computed column ensuring that if two rows have different values in col1 or col2 have different values in col4 
) ON [PRIMARY]

Data

Data untuk eksperimen adalah sebagai berikut

col1    col2    col3    col4
1       1       1       11
1       2       2       12
1       2       3       12
1       3       4       13
1       3       5       13
1       3       6       13
1       4       7       14
1       4       8       14
1       4       9       14
1       4       10      14
2       1       11      21
2       1       12      21
2       1       13      21
2       1       14      21
2       2       15      22
2       2       16      22
2       2       17      22
2       3       18      23
2       3       19      23
2       4       20      24

Langkah 1: Memfilter menurut col1

SELECT * FROM StatsTest WHERE col1=1

Seperti yang diharapkan, Pengoptimal Kueri menebak jumlah baris yang tepat. Jumlah Baris aktual = 10 dan Perkiraan Jumlah Baris = 10

Langkah 2: Memfilter menurut col2

SELECT * FROM StatsTest WHERE col2=1

Sekali lagi kami memiliki estimasi yang sempurna.

Jumlah Baris aktual = 5 dan Perkiraan Jumlah Baris = 5

Langkah 3: Memfilter menurut col1 dan col2

SELECT * FROM StatsTest WHERE col1=1 AND col2=1

Di sini estimasi jauh dari mendekati jumlah baris aktual. Jumlah Baris aktual = 1 dan Perkiraan Jumlah Baris = 3.53553

Masalahnya adalah bahwa implikator analizer query mengasumsikan bahwa col1 dan col2 adalah independen tetapi tidak.

Langkah 4: Memfilter menurut col4

SELECT * FROM StatsTest WHERE col4 = 11

Saya dapat memfilter menurut col4 = 11 untuk mendapatkan hasil yang sama dengan kueri pada Langkah 3, karena col4 adalah kolom yang dihitung dan menurut cara itu telah didefinisikan col1 = 1 dan col2 = 1 setara dengan col4 = 11 Di sini, namun , seperti yang diharapkan, estimasi ini sempurna.

Jumlah Baris aktual = 1 dan Estimasi Jumlah Baris = 1

Kesimpulan / Pertanyaan

¿Apakah solusi buatan dan tidak elegan ini satu-satunya pilihan yang tersedia untuk mencapai estimasi yang akurat ketika berhadapan dengan penyaringan dengan dua atau lebih kolom yang tidak independen? ¿Apakah kolom yang dihitung dan filter oleh kolom yang dihitung benar-benar perlu untuk mendapatkan presisi yang sebenarnya?

Contoh dalam sqlfiddle

JGA
sumber
Mengapa tidak membuat beberapa indeks di col1 / 2?
LowlyDBA
Sebenarnya saya melakukannya tetapi saya tidak memasukkan di sini karena itu tidak berhasil. Untuk histogram hanya kolom pertama yang dipertimbangkan dan kepadatan hanya mempertimbangkan jumlah nilai yang berbeda dan bukan distribusi mereka
JGA

Jawaban:

15

Apakah histogram multikolom dimungkinkan?

Bukan histogram multi dimensi yang benar, tidak.

Apakah solusi buatan dan tidak elegan ini satu-satunya pilihan yang tersedia untuk mencapai estimasi yang akurat ketika berhadapan dengan penyaringan dengan dua atau lebih kolom yang tidak independen?

SQL Server memang mendukung statistik "multi-kolom" , tetapi mereka hanya menangkap informasi kepadatan rata-rata (korelasi) selain histogram pada kolom bernama pertama. Mereka hanya berguna untuk perbandingan kesetaraan.

Informasi kepadatan rata-rata tidak menangkap detail apa pun, sehingga Anda akan mendapatkan selektivitas yang sama untuk setiap pasangan nilai pada objek statistik dua kolom. Dalam beberapa kasus, statistik multi-kolom bisa cukup baik, dan lebih baik daripada tidak sama sekali. Statistik multi-kolom secara otomatis dibangun di atas indeks multi-kolom.

Bergantung pada versi SQL Server, Anda mungkin juga dapat menggunakan indeks yang difilter dan statistik yang difilter :

-- Filtered statistics example
CREATE STATISTICS stats_StatsTest_col2_col1_eq_1
ON dbo.StatsTest (col2)
WHERE col1 = 1;

CREATE STATISTICS stats_StatsTest_col2_col1_eq_2
ON dbo.StatsTest (col2)
WHERE col1 = 2;

Atau Anda dapat membangun tampilan yang diindeks (yang dapat mendukung indeks dan statistik sendiri). Pandangan yang diindeks adalah mekanisme di balik DATE_CORRELATION_OPTIMIZATIONpengaturan basis data , fitur yang sedikit digunakan untuk korelasi antar-tabel, tetapi yang berlaku untuk semangat pertanyaan.

Apakah kolom yang dihitung dan filter oleh kolom yang dihitung benar-benar diperlukan untuk mendapatkan ketepatan yang sebenarnya?

Ini bukan satu-satunya metode. Selain hal-hal yang telah disebutkan, Anda juga bisa menentukan definisi tekstual yang tepat dari kolom yang dihitung dan optimizer umumnya akan mencocokkannya dengan statistik pada kolom yang dihitung.

Ada juga jejak jejak yang mengubah asumsi yang dibuat tentang korelasi multi-kolom. Juga, asumsi korelasi default di SQL Server 2014 (dengan penduga kardinalitas baru diaktifkan) diubah dari Kemerdekaan ke Pengembalian Eksponensial (lebih detail di sini dan di sini ). Pada akhirnya, ini hanya asumsi yang berbeda. Akan lebih baik dalam banyak kasus, dan lebih buruk dalam kasus lain.

Ketepatan yang tepat dalam estimasi kardinalitas tidak selalu diperlukan untuk mendapatkan rencana eksekusi yang baik. Selalu ada trade-off antara menghasilkan rencana yang dapat digunakan kembali untuk nilai parameter yang berbeda, dan rencana yang optimal untuk eksekusi tertentu, tetapi tidak digunakan kembali.

Paul White 9
sumber