Benjamin Nevarez adalah konsultan independen yang berbasis di Los Angeles, California yang berspesialisasi dalam penyetelan dan pengoptimalan kueri SQL Server. Dia adalah penulis "SQL Server 2014 Query Tuning &Optimization" dan "Inside the SQL Server Query Optimizer" dan rekan penulis "SQL Server 2012 Internals". Dengan pengalaman lebih dari 20 tahun dalam database relasional, Benjamin juga telah menjadi pembicara di banyak konferensi SQL Server, termasuk PASS Summit, SQL Server Connections, dan SQLBits. Blog Benjamin dapat ditemukan di http://www.benjaminnevarez.com dan dia juga dapat dihubungi melalui email di admin di benjaminnevarez dot com dan di twitter di @BenjaminNevarez.
Masalah utama dengan memperbarui statistik dalam tabel besar di SQL Server adalah bahwa seluruh tabel selalu harus dipindai, misalnya saat menggunakan WITH FULLSCAN
pilihan, meskipun hanya data terbaru yang berubah. Hal ini juga berlaku saat menggunakan partisi:meskipun hanya partisi terbaru yang berubah sejak terakhir kali statistik diperbarui, memperbarui statistik lagi diperlukan untuk memindai seluruh tabel termasuk semua partisi yang tidak berubah. Statistik tambahan, fitur baru SQL Server 2014, dapat membantu mengatasi masalah ini.
Dengan menggunakan statistik inkremental, Anda hanya dapat memperbarui partisi atau partisi yang Anda perlukan dan informasi pada partisi ini akan digabungkan dengan informasi yang ada untuk membuat objek statistik akhir. Keuntungan lain dari statistik inkremental adalah persentase perubahan data yang diperlukan untuk memicu pembaruan otomatis statistik sekarang bekerja pada tingkat partisi yang pada dasarnya berarti bahwa sekarang hanya 20% baris yang diubah (perubahan pada kolom statistik utama) per partisi yang diperlukan. Sayangnya histogram masih terbatas pada 200 langkah untuk seluruh objek statistik dalam versi SQL Server ini.
Mari kita lihat contoh bagaimana Anda dapat memperbarui statistik pada tingkat partisi untuk mengeksplorasi perilakunya setidaknya pada SQL Server 2014 CTP2. Pertama kita perlu membuat tabel yang dipartisi menggunakan database AdventureWorks2012:
CREATE PARTITION FUNCTION TransactionRangePF1 (DATETIME) AS RANGE RIGHT FOR VALUES ( '20071001', '20071101', '20071201', '20080101', '20080201', '20080301', '20080401', '20080501', '20080601', '20080701', '20080801' ); GO CREATE PARTITION SCHEME TransactionsPS1 AS PARTITION TransactionRangePF1 TO ( [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY] ); GO CREATE TABLE dbo.TransactionHistory ( TransactionID INT NOT NULL, -- not bothering with IDENTITY here ProductID INT NOT NULL, ReferenceOrderID INT NOT NULL, ReferenceOrderLineID INT NOT NULL DEFAULT (0), TransactionDate DATETIME NOT NULL DEFAULT (GETDATE()), TransactionType NCHAR(1) NOT NULL, Quantity INT NOT NULL, ActualCost MONEY NOT NULL, ModifiedDate DATETIME NOT NULL DEFAULT (GETDATE()), CONSTRAINT CK_TransactionType CHECK (UPPER(TransactionType) IN (N'W', N'S', N'P')) ) ON TransactionsPS1 (TransactionDate); GO
Catatan:Untuk detail tentang partisi dan CREATE PARTITION FUNCTION / SCHEME
pernyataan silakan merujuk ke Tabel dan Indeks yang Dipartisi di Buku Daring.
Saat ini kami memiliki data untuk mengisi 12 partisi. Mari kita mulai dengan mengisi terlebih dahulu hanya 11.
INSERT INTO dbo.TransactionHistory SELECT * FROM Production.TransactionHistory WHERE TransactionDate < '2008-08-01';
Jika diperlukan, Anda dapat menggunakan pernyataan berikut untuk memeriksa isi partisi:
SELECT * FROM sys.partitions WHERE object_id = OBJECT_ID('dbo.TransactionHistory');
Mari kita membuat objek statistik tambahan menggunakan CREATE STATISTICS
pernyataan dengan INCREMENTAL
baru klausa diatur ke ON
(OFF
adalah default):
CREATE STATISTICS incrstats ON dbo.TransactionHistory(TransactionDate) WITH FULLSCAN, INCREMENTAL = ON;
Anda juga dapat membuat statistik tambahan saat membuat indeks menggunakan STATISTICS_INCREMENTAL
baru klausa dari CREATE INDEX
pernyataan.
Anda dapat memeriksa objek statistik yang dibuat menggunakan DBCC
:
DBCC SHOW_STATISTICS('dbo.TransactionHistory', incrstats);
Antara lain, Anda akan melihat bahwa histogram memiliki 200 langkah (hanya 3 langkah terakhir yang ditampilkan di sini):
RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | |
198 | 25-07-2008 00:00:00.000 | 187 | 100 | 2 |
199 | 27-07-2008 00:00:00.000 | 103 | 101 | 1 |
200 | 31-07-2008 00:00:00.000 | 281 | 131 | 3 |
Hasil DBCC awal
Jadi kita sudah memiliki langkah maksimum dalam objek statistik. Apa yang akan terjadi jika Anda menambahkan data ke partisi baru? Mari kita tambahkan data ke partisi 12:
INSERT INTO dbo.TransactionHistory SELECT * FROM Production.TransactionHistory WHERE TransactionDate >= '2008-08-01';
Sekarang, kami memperbarui objek statistik menggunakan pernyataan berikut:
UPDATE STATISTICS dbo.TransactionHistory(incrstats) WITH RESAMPLE ON PARTITIONS(12);
Perhatikan sintaks baru yang menentukan partisi, di mana Anda dapat menentukan beberapa partisi, dipisahkan dengan koma. UPDATE STATISTICS
pernyataan membaca partisi yang ditentukan dan kemudian menggabungkan hasilnya dengan objek statistik yang ada untuk membangun statistik global. Perhatikan RESAMPLE
ayat; ini diperlukan karena statistik partisi harus memiliki tingkat sampel yang sama untuk digabungkan guna membangun statistik global. Meskipun hanya partisi tertentu yang dipindai, Anda dapat melihat bahwa SQL Server telah mengatur ulang histogram. Tiga langkah terakhir sekarang menunjukkan data untuk partisi yang ditambahkan. Anda juga dapat membandingkan yang asli dengan histogram baru untuk perbedaan kecil lainnya:
RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | |
197 | 31-07-2008 00:00:00.000 | 150 | 131 | 2 |
198 | 2008-08-12 00:00:00.000 | 300 | 36 | 9 |
199 | 22-08-2008 00:00:00.000 | 229 | 43 | 7 |
200 | 03-09-2008 00:00:00.000 | 363 | 37 | 11 |
Hasil DBCC setelah pembaruan tambahan
Jika karena alasan apa pun Anda ingin menonaktifkan statistik inkremental, Anda dapat menggunakan pernyataan berikut untuk kembali ke perilaku awal (atau secara opsional lepaskan objek statistik dan buat yang baru).
UPDATE STATISTICS dbo.TransactionHistory(incrstats) WITH FULLSCAN, INCREMENTAL = OFF;
Setelah menonaktifkan statistik inkremental mencoba memperbarui partisi seperti yang ditunjukkan sebelumnya akan mengembalikan pesan kesalahan berikut:
Msg 9111, Level 16, Status 1PERBARUI STATISTIK PADA PARTISI sintaks tidak didukung untuk statistik non-incremental.
Terakhir, Anda juga dapat mengaktifkan statistik tambahan untuk statistik otomatis Anda di tingkat basis data, jika diperlukan. Ini membutuhkan INCREMENTAL = ON
klausa dalam ALTER DATABASE
pernyataan dan jelas juga membutuhkan AUTO_CREATE_STATISTICS
setel ke ON
.