Bagaimana jumlah langkah Histogram diputuskan dalam Statistik

11

Bagaimana jumlah langkah histogram diputuskan dalam Statistik di SQL Server?

Mengapa dibatasi hingga 200 langkah meskipun kolom kunci saya memiliki lebih dari 200 nilai yang berbeda? Apakah ada faktor penentu?


Demo

Definisi skema

CREATE TABLE histogram_step
  (
     id   INT IDENTITY(1, 1),
     name VARCHAR(50),
     CONSTRAINT pk_histogram_step PRIMARY KEY (id)
  )

Memasukkan 100 catatan ke meja saya

INSERT INTO histogram_step
            (name)
SELECT TOP 100 name
FROM   sys.syscolumns

Memperbarui dan memeriksa statistik

UPDATE STATISTICS histogram_step WITH fullscan

DBCC show_statistics('histogram_step', pk_histogram_step)

Langkah histogram:

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
|            1 |          0 |       1 |                   0 |              1 |
|            3 |          1 |       1 |                   1 |              1 |
|            5 |          1 |       1 |                   1 |              1 |
|            7 |          1 |       1 |                   1 |              1 |
|            9 |          1 |       1 |                   1 |              1 |
|           11 |          1 |       1 |                   1 |              1 |
|           13 |          1 |       1 |                   1 |              1 |
|           15 |          1 |       1 |                   1 |              1 |
|           17 |          1 |       1 |                   1 |              1 |
|           19 |          1 |       1 |                   1 |              1 |
|           21 |          1 |       1 |                   1 |              1 |
|           23 |          1 |       1 |                   1 |              1 |
|           25 |          1 |       1 |                   1 |              1 |
|           27 |          1 |       1 |                   1 |              1 |
|           29 |          1 |       1 |                   1 |              1 |
|           31 |          1 |       1 |                   1 |              1 |
|           33 |          1 |       1 |                   1 |              1 |
|           35 |          1 |       1 |                   1 |              1 |
|           37 |          1 |       1 |                   1 |              1 |
|           39 |          1 |       1 |                   1 |              1 |
|           41 |          1 |       1 |                   1 |              1 |
|           43 |          1 |       1 |                   1 |              1 |
|           45 |          1 |       1 |                   1 |              1 |
|           47 |          1 |       1 |                   1 |              1 |
|           49 |          1 |       1 |                   1 |              1 |
|           51 |          1 |       1 |                   1 |              1 |
|           53 |          1 |       1 |                   1 |              1 |
|           55 |          1 |       1 |                   1 |              1 |
|           57 |          1 |       1 |                   1 |              1 |
|           59 |          1 |       1 |                   1 |              1 |
|           61 |          1 |       1 |                   1 |              1 |
|           63 |          1 |       1 |                   1 |              1 |
|           65 |          1 |       1 |                   1 |              1 |
|           67 |          1 |       1 |                   1 |              1 |
|           69 |          1 |       1 |                   1 |              1 |
|           71 |          1 |       1 |                   1 |              1 |
|           73 |          1 |       1 |                   1 |              1 |
|           75 |          1 |       1 |                   1 |              1 |
|           77 |          1 |       1 |                   1 |              1 |
|           79 |          1 |       1 |                   1 |              1 |
|           81 |          1 |       1 |                   1 |              1 |
|           83 |          1 |       1 |                   1 |              1 |
|           85 |          1 |       1 |                   1 |              1 |
|           87 |          1 |       1 |                   1 |              1 |
|           89 |          1 |       1 |                   1 |              1 |
|           91 |          1 |       1 |                   1 |              1 |
|           93 |          1 |       1 |                   1 |              1 |
|           95 |          1 |       1 |                   1 |              1 |
|           97 |          1 |       1 |                   1 |              1 |
|           99 |          1 |       1 |                   1 |              1 |
|          100 |          0 |       1 |                   0 |              1 |
+--------------+------------+---------+---------------------+----------------+

Seperti yang bisa kita lihat ada 53 langkah dalam histogram.

Sekali lagi memasukkan beberapa ribu catatan

INSERT INTO histogram_step
            (name)
SELECT TOP 10000 b.name
FROM   sys.syscolumns a
       CROSS JOIN sys.syscolumns b

Memperbarui dan memeriksa statistik

UPDATE STATISTICS histogram_step WITH fullscan

DBCC show_statistics('histogram_step', pk_histogram_step)

Sekarang langkah histogram dikurangi menjadi 4 langkah

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
|            1 |          0 |       1 |                   0 |              1 |
|        10088 |      10086 |       1 |               10086 |              1 |
|        10099 |         10 |       1 |                  10 |              1 |
|        10100 |          0 |       1 |                   0 |              1 |
+--------------+------------+---------+---------------------+----------------+

Sekali lagi memasukkan beberapa ribu catatan

INSERT INTO histogram_step
            (name)
SELECT TOP 100000 b.name
FROM   sys.syscolumns a
       CROSS JOIN sys.syscolumns b

Memperbarui dan memeriksa statistik

UPDATE STATISTICS histogram_step WITH fullscan

DBCC show_statistics('histogram_step', pk_histogram_step) 

Sekarang langkah histogram dikurangi menjadi 3 langkah

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
|            1 |          0 |       1 |                   0 |              1 |
|       110099 |     110097 |       1 |              110097 |              1 |
|       110100 |          0 |       1 |                   0 |              1 |
+--------------+------------+---------+---------------------+----------------+

Dapatkah seseorang memberi tahu saya bagaimana langkah-langkah ini diputuskan?

P ரதீப்
sumber
3
200 adalah pilihan sewenang-wenang. Ini tidak ada hubungannya dengan berapa banyak nilai berbeda yang Anda miliki di tabel tertentu. Jika Anda ingin tahu mengapa 200 dipilih, Anda harus bertanya kepada seorang insinyur dari tim SQL Server 1990-an, bukan rekan kerja Anda
Aaron Bertrand
1
@AaronBertrand - Terima kasih .. Jadi bagaimana langkah-langkah ini diputuskan
P ரதீப்
1
Tidak ada keputusan. Batas atas adalah 200. Periode. Secara teknis, ini tahun 201, tapi itu cerita untuk hari lain.
Aaron Bertrand
1
Saya telah mengajukan pertanyaan serupa tentang perkiraan intrastep, mungkin bisa membantu dba.stackexchange.com/questions/148523/…
jesijesi

Jawaban:

14

Saya akan membatasi posting ini untuk membahas statistik satu kolom karena sudah cukup panjang dan Anda tertarik pada bagaimana SQL Server memasukkan data ke dalam langkah-langkah histogram. Untuk statistik multi-kolom histogram hanya dibuat pada kolom terkemuka.

Ketika SQL Server menentukan bahwa pembaruan statistik diperlukan itu memulai permintaan tersembunyi yang membaca semua data tabel atau sampel data tabel. Anda dapat melihat pertanyaan ini dengan acara yang diperpanjang. Ada fungsi yang disebut StatMandalam SQL Server yang terlibat dengan membuat histogram. Untuk objek statistik sederhana setidaknya ada dua jenis StatMankueri yang berbeda (ada kueri yang berbeda untuk pembaruan stat cepat dan saya menduga bahwa fitur statistik tambahan pada tabel yang dipartisi juga menggunakan kueri yang berbeda).

Yang pertama hanya mengambil semua data dari tabel tanpa penyaringan. Anda dapat melihat ini ketika tabel sangat kecil atau Anda mengumpulkan statistik dengan FULLSCANopsi:

CREATE TABLE X_SHOW_ME_STATMAN (N INT);
CREATE STATISTICS X_STAT_X_SHOW_ME_STATMAN ON X_SHOW_ME_STATMAN (N);

-- after gathering stats with 1 row in table
SELECT StatMan([SC0]) FROM
(
    SELECT TOP 100 PERCENT [N] AS [SC0] 
    FROM [dbo].[X_SHOW_ME_STATMAN] WITH (READUNCOMMITTED)
    ORDER BY [SC0] 
) AS _MS_UPDSTATS_TBL 
OPTION (MAXDOP 16);

SQL Server mengambil ukuran sampel otomatis berdasarkan ukuran tabel (saya pikir itu adalah jumlah baris dan halaman dalam tabel). Jika tabel terlalu besar maka ukuran sampel otomatis turun di bawah 100%. Inilah yang saya dapatkan untuk tabel yang sama dengan baris 1M:

-- after gathering stats with 1 M rows in table
SELECT StatMan([SC0], [SB0000]) FROM 
(
    SELECT TOP 100 PERCENT [SC0], step_direction([SC0]) over (order by NULL) AS [SB0000] 
    FROM 
    (
        SELECT [N] AS [SC0] 
        FROM [dbo].[X_SHOW_ME_STATMAN] TABLESAMPLE SYSTEM (6.666667e+001 PERCENT) WITH (READUNCOMMITTED) 
    ) AS _MS_UPDSTATS_TBL_HELPER 
    ORDER BY [SC0], [SB0000] 
) AS _MS_UPDSTATS_TBL
OPTION (MAXDOP 1);

TABLESAMPLEadalah didokumentasikan tetapi Statman dan step_direction tidak. di sini SQL Server sampel sekitar 66,6% dari data dari tabel untuk membuat histogram. Artinya, Anda bisa mendapatkan jumlah langkah histogram yang berbeda saat memperbarui statistik (tanpa FULLSCAN) pada data yang sama. Saya belum pernah mengamati ini dalam praktik tetapi saya tidak melihat mengapa itu tidak mungkin.

Mari kita jalankan beberapa tes pada data sederhana untuk melihat bagaimana statistik berubah seiring waktu. Di bawah ini adalah beberapa kode tes yang saya tulis untuk memasukkan bilangan bulat berurutan ke dalam tabel, mengumpulkan statistik setelah setiap sisipan, dan menyimpan informasi tentang statistik ke dalam tabel hasil. Mari kita mulai dengan memasukkan 1 baris sekaligus hingga 10.000. Test bed:

DECLARE
@stats_id INT,
@table_object_id INT,
@rows_per_loop INT = 1,
@num_of_loops INT = 10000,
@loop_num INT;

BEGIN
    SET NOCOUNT ON;

    TRUNCATE TABLE X_STATS_RESULTS;

    SET @table_object_id = OBJECT_ID ('X_SEQ_NUM');
    SELECT @stats_id = stats_id FROM sys.stats
    WHERE OBJECT_ID = @table_object_id
    AND name = 'X_STATS_SEQ_INT_FULL';

    SET @loop_num = 0;
    WHILE @loop_num < @num_of_loops
    BEGIN
        SET @loop_num = @loop_num + 1;

        INSERT INTO X_SEQ_NUM WITH (TABLOCK)
        SELECT @rows_per_loop * (@loop_num - 1) + N FROM dbo.GetNums(@rows_per_loop);

        UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN; -- can comment out FULLSCAN as needed

        INSERT INTO X_STATS_RESULTS WITH (TABLOCK)
        SELECT 'X_STATS_SEQ_INT_FULL', @rows_per_loop * @loop_num, rows_sampled, steps 
        FROM sys.dm_db_stats_properties(@table_object_id, @stats_id);
        END;
END;

Untuk data ini jumlah langkah histogram dengan cepat meningkat menjadi 200 (pertama-tama menyentuh jumlah maksimum langkah dengan 397 baris), tetap pada 199 atau 200 hingga 1485 baris ada di tabel, kemudian perlahan-lahan menurun hingga histogram hanya memiliki 3 atau 4 Langkah. Berikut adalah grafik dari semua data:

grafik pertama

Begini histogramnya untuk baris 10rb:

RANGE_HI_KEY    RANGE_ROWS  EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
1               0           1       0                   1
9999            9997        1       9997                1
10000           0           1       0                   1

Apakah masalah bahwa histogram hanya memiliki 3 langkah? Sepertinya informasi dipertahankan dari sudut pandang kami. Perhatikan bahwa karena datatype adalah INTEGER kita bisa mengetahui berapa banyak baris dalam tabel untuk setiap bilangan bulat dari 1 - 10.000. Biasanya SQL Server juga bisa mengetahuinya, meskipun ada beberapa kasus di mana ini tidak cukup berhasil . Lihat posting SE ini untuk contohnya.

Menurut Anda apa yang akan terjadi jika kami menghapus satu baris dari tabel dan memperbarui statistik? Idealnya kita akan mendapatkan langkah histogram lain untuk menunjukkan bahwa integer yang hilang tidak lagi ada dalam tabel.

DELETE FROM X_SEQ_NUM
WHERE X_NUM  = 1000;

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- still 3 steps

DELETE FROM X_SEQ_NUM
WHERE X_NUM  IN (2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000);

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- still 3 steps

Itu sedikit mengecewakan. Jika kami membuat histogram dengan tangan, kami akan menambahkan langkah untuk setiap nilai yang hilang. SQL Server menggunakan algoritme tujuan umum sehingga untuk beberapa set data, kami mungkin dapat membuat histogram yang lebih cocok daripada kode yang digunakannya. Tentu saja, perbedaan praktis antara mendapatkan 0 atau 1 baris dari tabel sangat kecil. Saya mendapatkan hasil yang sama ketika menguji dengan 20.000 baris yang masing-masing bilangan bulat memiliki 2 baris dalam tabel. Histogram tidak mendapatkan langkah saat saya menghapus data.

RANGE_HI_KEY    RANGE_ROWS  EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
1               0           2       0                   1
9999            19994       2       9997                2
10000           0           2       0                   1

Jika saya menguji dengan 1 juta baris dengan setiap bilangan bulat memiliki 100 baris dalam tabel, saya mendapatkan hasil yang sedikit lebih baik, tetapi saya masih dapat membuat histogram yang lebih baik dengan tangan.

truncate table X_SEQ_NUM;

BEGIN TRANSACTION;
INSERT INTO X_SEQ_NUM WITH (TABLOCK)
SELECT N FROM dbo.GetNums(10000);
GO 100
COMMIT TRANSACTION;

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- 4 steps

DELETE FROM X_SEQ_NUM
WHERE X_NUM  = 1000;

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- now 5 steps with a RANGE_HI_KEY of 998 (?)

DELETE FROM X_SEQ_NUM
WHERE X_NUM  IN (2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000);

UPDATE STATISTICS X_SEQ_NUM X_STATS_SEQ_INT_FULL WITH FULLSCAN;

DBCC SHOW_STATISTICS ('X_SEQ_NUM', 'X_STATS_SEQ_INT_FULL'); -- still 5 steps

Histogram terakhir:

RANGE_HI_KEY    RANGE_ROWS  EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
1               0           100     0                   1
998             99600       100     996                 100
3983            298100      100     2981                100
9999            600900      100     6009                100
10000           0           100     0                   1

Mari kita uji lebih lanjut dengan integer berurutan tetapi dengan lebih banyak baris dalam tabel. Perhatikan bahwa untuk tabel yang terlalu kecil secara manual menentukan ukuran sampel tidak akan berpengaruh, jadi saya akan menambahkan 100 baris di setiap sisipan dan mengumpulkan statistik setiap kali hingga 1 juta baris. Saya melihat pola yang sama seperti sebelumnya, kecuali sekali saya mendapatkan 637300 baris dalam tabel saya tidak lagi sampel 100% dari baris dalam tabel dengan tingkat sampel default. Saat saya mendapatkan baris, jumlah langkah histogram meningkat. Mungkin ini karena SQL Server berakhir dengan lebih banyak kesenjangan dalam data karena jumlah baris yang tidak dicampuri dalam tabel meningkat. Saya tidak mencapai 200 langkah bahkan pada baris 1 M, tetapi jika saya terus menambahkan baris saya berharap saya akan sampai di sana dan akhirnya mulai turun kembali.

grafik 2

Sumbu X adalah jumlah baris dalam tabel. Ketika jumlah baris bertambah, baris-baris yang diambil sampel sedikit bervariasi dan tidak melebihi 650 ribu.

Sekarang mari kita lakukan beberapa tes sederhana dengan data VARCHAR.

CREATE TABLE X_SEQ_STR (X_STR VARCHAR(5));
CREATE STATISTICS X_SEQ_STR ON X_SEQ_STR(X_STR);

Di sini saya memasukkan 200 angka (sebagai string) bersama dengan NULL.

INSERT INTO X_SEQ_STR
SELECT N FROM dbo.GetNums(200)
UNION ALL
SELECT NULL;

UPDATE STATISTICS X_SEQ_STR X_SEQ_STR ;

DBCC SHOW_STATISTICS ('X_SEQ_STR', 'X_SEQ_STR'); -- 111 steps, RANGE_ROWS is 0 or 1 for all steps

Perhatikan bahwa NULL selalu mendapatkan langkah histogram sendiri ketika ditemukan dalam tabel. SQL Server bisa memberi saya tepat 201 langkah untuk menyimpan semua informasi tetapi tidak melakukan itu. Informasi teknis hilang karena '1111' antara '1' dan '2' misalnya.

Sekarang mari kita coba memasukkan karakter yang berbeda dan bukan hanya bilangan bulat:

truncate table X_SEQ_STR;

INSERT INTO X_SEQ_STR
SELECT CHAR(10 + N) FROM dbo.GetNums(200)
UNION ALL
SELECT NULL;

UPDATE STATISTICS X_SEQ_STR X_SEQ_STR ;

DBCC SHOW_STATISTICS ('X_SEQ_STR', 'X_SEQ_STR'); -- 95 steps, RANGE_ROWS is 0 or 1 or 2

Tidak ada perbedaan nyata dari tes terakhir.

Sekarang mari kita coba memasukkan karakter tetapi menempatkan angka yang berbeda dari setiap karakter di dalam tabel. Misalnya, CHAR(11)memiliki 1 baris, CHAR(12)memiliki 2 baris, dll.

truncate table X_SEQ_STR;

DECLARE
@loop_num INT;

BEGIN
    SET NOCOUNT ON;

    SET @loop_num = 0;
    WHILE @loop_num < 200
    BEGIN
        SET @loop_num = @loop_num + 1;

        INSERT INTO X_SEQ_STR WITH (TABLOCK)
        SELECT CHAR(10 + @loop_num) FROM dbo.GetNums(@loop_num);
    END;
END;

UPDATE STATISTICS X_SEQ_STR X_SEQ_STR ;

DBCC SHOW_STATISTICS ('X_SEQ_STR', 'X_SEQ_STR'); -- 148 steps, most with RANGE_ROWS of 0

Seperti sebelumnya saya masih belum mendapatkan persis 200 langkah histogram. Namun, banyak langkah memiliki RANGE_ROWS0.

Untuk tes terakhir, saya akan memasukkan string acak 5 karakter di setiap loop dan mengumpulkan statistik setiap kali. Berikut kode string acak:

char((rand()*25 + 65))+char((rand()*25 + 65))+char((rand()*25 + 65))+char((rand()*25 + 65))+char((rand()*25 + 65))

Berikut ini adalah grafik baris dalam tabel vs langkah-langkah histogram: grafik 3

Perhatikan bahwa jumlah langkah tidak turun di bawah 100 setelah mulai naik dan turun. Saya telah mendengar dari suatu tempat (tetapi tidak dapat sumber sekarang) bahwa algoritma membangun histogram SQL Server menggabungkan langkah-langkah histogram karena kehabisan ruang untuk mereka. Jadi Anda bisa berakhir dengan perubahan drastis dalam jumlah langkah hanya dengan menambahkan sedikit data. Inilah satu contoh data yang menurut saya menarik:

ROWS_IN_TABLE   ROWS_SAMPLED    STEPS
36661           36661           133
36662           36662           143
36663           36663           143
36664           36664           141
36665           36665           138

Bahkan ketika pengambilan sampel dengan FULLSCAN, menambahkan satu baris dapat meningkatkan jumlah langkah dengan 10, tetap konstan, lalu menguranginya 2, lalu menguranginya dengan 3.

Apa yang bisa kita simpulkan dari semua ini? Saya tidak bisa membuktikan semua ini, tetapi pengamatan ini tampaknya benar:

  • SQL Server menggunakan algoritma penggunaan umum untuk membuat histogram. Untuk beberapa distribusi data, dimungkinkan untuk membuat representasi data yang lebih lengkap dengan tangan.
  • Jika ada data NULL dalam tabel dan permintaan statistik menemukannya maka data NULL selalu mendapatkan langkah histogram sendiri.
  • Nilai minimum yang ditemukan dalam tabel mendapatkan langkah histogram sendiri dengan RANGE_ROWS= 0.
  • Nilai maksimum yang ditemukan di tabel akan menjadi final RANGE_HI_KEYdalam tabel.
  • Sebagai SQL Server sampel lebih banyak data, mungkin perlu menggabungkan langkah-langkah yang ada untuk memberikan ruang bagi data baru yang ditemukannya. Jika Anda melihat histogram yang cukup Anda mungkin melihat nilai-nilai umum diulang untuk DISTINCT_RANGE_ROWSatau RANGE_ROWS. Misalnya, 255 muncul beberapa kali untuk RANGE_ROWSdan DISTINCT_RANGE_ROWSuntuk ujian akhir di sini.
  • Untuk distribusi data sederhana, Anda mungkin melihat SQL Server menggabungkan data sekuensial ke dalam satu langkah histogram yang tidak menyebabkan hilangnya informasi. Namun saat menambahkan kesenjangan ke data, histogram mungkin tidak menyesuaikan dengan cara yang Anda harapkan.

Kapan semua ini menjadi masalah? Ini masalah ketika kueri berkinerja buruk karena histogram yang tidak dapat mewakili distribusi data dengan cara pengoptimal kueri untuk membuat keputusan yang baik. Saya pikir ada kecenderungan untuk berpikir bahwa memiliki lebih banyak langkah-langkah histogram selalu lebih baik dan untuk itu ada kekhawatiran ketika SQL Server menghasilkan histogram pada jutaan baris atau lebih tetapi tidak menggunakan langkah-langkah tepat 200 atau 201 histogram. Namun, saya telah melihat banyak masalah statistik bahkan ketika histogram memiliki 200 atau 201 langkah. Kami tidak memiliki kendali atas berapa banyak langkah histogram yang dihasilkan SQL Server untuk objek statistik jadi saya tidak akan khawatir tentang hal itu. Namun, ada beberapa langkah yang bisa Anda ambil ketika Anda mengalami kueri berkinerja buruk yang disebabkan oleh masalah statistik. Saya akan memberikan gambaran yang sangat singkat.

Mengumpulkan statistik secara penuh dapat membantu dalam beberapa kasus. Untuk tabel yang sangat besar ukuran sampel otomatis mungkin kurang dari 1% dari baris dalam tabel. Terkadang hal itu dapat menyebabkan rencana yang buruk tergantung pada gangguan data di kolom. Dokumentasi Microsoft untuk CREATE STATISTICS dan UPDATE STATISTICS mengatakan:

SAMPLE berguna untuk kasus khusus di mana rencana kueri, berdasarkan pengambilan sampel default, tidak optimal. Dalam sebagian besar situasi, tidak perlu menentukan SAMPLE karena pengoptimal permintaan sudah menggunakan pengambilan sampel dan menentukan ukuran sampel yang signifikan secara statistik secara default, seperti yang diperlukan untuk membuat rencana kueri berkualitas tinggi.

Untuk sebagian besar beban kerja, pemindaian penuh tidak diperlukan, dan pengambilan sampel standar memadai. Namun, beban kerja tertentu yang sensitif terhadap distribusi data yang bervariasi mungkin memerlukan ukuran sampel yang meningkat, atau bahkan pemindaian penuh.

Dalam beberapa kasus, membuat statistik yang difilter dapat membantu. Anda mungkin memiliki kolom dengan data miring dan banyak nilai berbeda yang berbeda. Jika ada nilai tertentu dalam data yang biasanya difilter pada Anda dapat membuat histogram statistik hanya untuk nilai-nilai umum tersebut. Pengoptimal kueri dapat menggunakan statistik yang ditentukan pada rentang data yang lebih kecil daripada statistik yang ditentukan pada semua nilai kolom. Anda masih tidak dijamin untuk mendapatkan 200 langkah dalam histogram, tetapi jika Anda membuat statistik yang difilter hanya pada satu nilai Anda akan langkah histogram nilai itu.

Menggunakan tampilan yang dipartisi adalah salah satu cara untuk secara efektif mendapatkan lebih dari 200 langkah untuk tabel. Misalkan Anda dapat dengan mudah membagi meja besar menjadi satu meja per tahun. Anda membuat UNION ALLtampilan yang menggabungkan semua tabel tahunan. Setiap tabel akan memiliki histogram sendiri. Perhatikan bahwa statistik inkremental baru yang diperkenalkan di SQL Server 2014 hanya memungkinkan pembaruan statistik menjadi lebih efisien. Pengoptimal kueri tidak akan menggunakan statistik yang dibuat per partisi.

Ada banyak lagi tes yang dapat dijalankan di sini, jadi saya mendorong Anda untuk bereksperimen. Saya melakukan pengujian ini pada SQL Server 2014 express sehingga benar-benar tidak ada yang menghentikan Anda.

Joe Obbish
sumber
4
Lihat google.com/patents/US6714938
Paul White 9