Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Statistik Tambahan SQL Server 2014

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 1
PERBARUI 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 .


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Solusi untuk INSERT ATAU UPDATE di SQL Server

  2. Eksekusi SQL Dinamis di SQL Server

  3. Bagaimana cara mengubah skema db ke dbo

  4. Cara Menggabungkan String di SQL Server dengan CONCAT()

  5. Cara Menemukan Format Tanggal yang Digunakan di Sesi Saat Ini di SQL Server (T-SQL)