Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Cara Lain untuk Melihat Pembaruan Otomatis pada Statistik

Kembali pada bulan April saya menulis tentang beberapa metode asli dalam SQL Server yang dapat digunakan untuk melacak pembaruan otomatis ke statistik. Tiga opsi yang saya berikan adalah SQL Trace, Extended Events, dan snapshot dari sys.dm_db_stats_properties. Meskipun ketiga opsi ini tetap berjalan (bahkan di SQL Server 2014, meskipun rekomendasi teratas saya masih XE), opsi tambahan yang saya perhatikan saat menjalankan beberapa tes baru-baru ini adalah SQL Sentry Plan Explorer.

Banyak dari Anda menggunakan Plan Explorer hanya untuk membaca rencana eksekusi, yang sangat bagus. Ini memiliki banyak manfaat dibandingkan Management Studio dalam hal meninjau rencana – dari hal-hal kecil, seperti dapat mengurutkan operator teratas dan dengan mudah melihat masalah perkiraan kardinalitas, hingga manfaat yang lebih besar, seperti menangani rencana yang kompleks dan besar dan dapat memilih satu pernyataan dalam batch untuk tinjauan rencana yang lebih mudah. Namun di balik visual yang memudahkan untuk membedah rencana, Plan Explorer juga menawarkan kemampuan untuk mengeksekusi kueri dan melihat rencana yang sebenarnya (daripada menjalankannya di Management Studio dan menyimpannya). Selain itu, saat Anda menjalankan rencana dari PE, ada informasi tambahan yang dapat berguna.

Mari kita mulai dengan demo yang saya gunakan dalam posting terbaru saya, Bagaimana Pembaruan Otomatis Statistik Dapat Mempengaruhi Kinerja Kueri. Saya mulai dengan database AdventureWorks2012, dan saya membuat salinan tabel SalesOrderHeader dengan lebih dari 200 juta baris. Tabel memiliki indeks berkerumun di SalesOrderID, dan indeks tidak berkerumun di ID Pelanggan, TanggalPesanan, SubTotal. [Sekali lagi:jika Anda akan melakukan tes berulang, ambil cadangan database ini pada saat ini untuk menghemat waktu.] Saya pertama kali memverifikasi jumlah baris saat ini dalam tabel, dan jumlah baris yang perlu diubah untuk meminta pembaruan otomatis:

SELECT
OBJECT_NAME([p].[object_id]) [TableName],
[si].[name] [IndexName],
[au].[type_desc] [Type],
[p].[rows] [RowCount],
([p].[rows]*.20) + 500 [UpdateThreshold],
[au].total_pages [PageCount],
(([au].[total_pages]*8)/1024)/1024 [TotalGB]
FROM [sys].[partitions] [p]
JOIN [sys].[allocation_units] [au] ON [p].[partition_id] = [au].[container_id]
JOIN [sys].[indexes] [si] on [p].[object_id] = [si].object_id and [p].[index_id] = [si].[index_id]
WHERE [p].[object_id] = OBJECT_ID(N'Sales.Big_SalesOrderHeader');


Big_SalesOrderHeader Informasi CIX dan NCI

Saya juga memverifikasi tajuk statistik saat ini untuk indeks:

DBCC SHOW_STATISTICS ('Sales.Big_SalesOrderHeader',[IX_Big_SalesOrderHeader_CustomerID_OrderDate_SubTotal]);


Statistik NCI:Saat Memulai

Prosedur tersimpan yang saya gunakan untuk pengujian sudah dibuat, tetapi untuk kelengkapan kodenya tercantum di bawah ini:

CREATE PROCEDURE Sales.usp_GetCustomerStats
@CustomerID INT,
@StartDate DATETIME,
@EndDate DATETIME
AS
BEGIN
  SET NOCOUNT ON;
 
  SELECT CustomerID, DATEPART(YEAR, OrderDate), DATEPART(MONTH, OrderDate), COUNT([SalesOrderID]) as Computed
    FROM [Sales].[Big_SalesOrderHeader]
    WHERE CustomerID = @CustomerID
    AND OrderDate BETWEEN @StartDate and @EndDate
    GROUP BY CustomerID, DATEPART(YEAR, OrderDate), DATEPART(MONTH, OrderDate)
    ORDER BY DATEPART(YEAR, OrderDate), DATEPART(MONTH, OrderDate);
END

Sebelumnya, saya memulai sesi Trace atau Extended Events, atau mengatur metode saya untuk memotret sys.dm_db_stats_properties ke sebuah tabel. Untuk contoh ini, saya baru saja menjalankan prosedur tersimpan di atas beberapa kali:

EXEC Sales.usp_GetCustomerStats 11331, '2012-08-01 00:00:00.000', '2012-08-31 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 11330, '2013-01-01 00:00:00.000', '2013-01-31 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 11506, '2012-11-01 00:00:00.000', '2012-11-30 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 17061, '2013-01-01 00:00:00.000', '2013-01-31 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 11711, '2013-03-01 00:00:00.000', '2013-03-31 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 15131, '2013-02-01 00:00:00.000', '2013-02-28 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 29837, '2012-10-01 00:00:00.000', '2012-10-31 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 15750, '2013-03-01 00:00:00.000', '2013-03-31 23:59:59.997'
GO

Saya kemudian memeriksa cache prosedur untuk memverifikasi jumlah eksekusi, dan juga memverifikasi paket yang di-cache:

SELECT
OBJECT_NAME([st].[objectid]),
[st].[text],
[qs].[execution_count],
[qs].[creation_time],
[qs].[last_execution_time],
[qs].[min_worker_time],
[qs].[max_worker_time],
[qs].[min_logical_reads],
[qs].[max_logical_reads],
[qs].[min_elapsed_time],
[qs].[max_elapsed_time],
[qp].[query_plan]
FROM [sys].[dm_exec_query_stats] [qs]
CROSS APPLY [sys].[dm_exec_sql_text]([qs].plan_handle) [st]
CROSS APPLY [sys].[dm_exec_query_plan]([qs].plan_handle) [qp]
WHERE [st].[text] LIKE '%usp_GetCustomerStats%'
AND OBJECT_NAME([st].[objectid]) IS NOT NULL;


Rencanakan Info Tembolok untuk SP:Saat Memulai


Rencana Kueri untuk Prosedur Tersimpan, menggunakan SQL Sentry Plan Explorer

Rencana tersebut dibuat pada 29-09-2014 23:23.01.

Selanjutnya saya menambahkan 61 juta baris ke tabel untuk membatalkan statistik saat ini, dan setelah penyisipan selesai, saya memeriksa jumlah baris:


Big_SalesOrderHeader Informasi CIX dan NCI:Setelah memasukkan 61 juta baris

Sebelum menjalankan prosedur tersimpan lagi, saya memverifikasi bahwa jumlah eksekusi tidak berubah, bahwa waktu_pembuatan masih 29-09-2014 23:23.01 untuk rencana, dan bahwa statistik belum diperbarui:


Rencanakan Info Cache untuk SP:Segera Setelah Sisipkan


Statistik NCI:Setelah Sisipan

Sekarang, di posting blog sebelumnya, saya menjalankan pernyataan di Management Studio, tetapi kali ini, saya menjalankan kueri langsung dari Plan Explorer, dan menangkap Rencana Aktual melalui PE (opsi dilingkari merah pada gambar di bawah).


Jalankan Prosedur Tersimpan dari Plan Explorer

Saat Anda menjalankan pernyataan dari PE, Anda harus memasukkan instance dan database yang ingin Anda hubungkan, dan kemudian Anda diberi tahu bahwa kueri akan dijalankan dan rencana aktual akan dikembalikan, tetapi hasilnya tidak akan dikembalikan. Perhatikan bahwa ini berbeda dari Management Studio, tempat Anda melihat hasilnya.

Setelah saya menjalankan prosedur tersimpan, dalam output saya tidak hanya mendapatkan rencana, tetapi saya melihat pernyataan apa yang dieksekusi:


Rencanakan keluaran Explorer setelah eksekusi SP (setelah penyisipan)

Ini cukup keren…selain melihat pernyataan yang dieksekusi dalam prosedur tersimpan, saya juga melihat pembaruan statistik, seperti yang saya lakukan ketika saya menangkap pembaruan menggunakan Extended Events atau SQL Trace. Seiring dengan eksekusi pernyataan, kita juga dapat melihat informasi CPU, durasi, dan IO. Sekarang – peringatan di sini adalah saya dapat melihat informasi ini jika Saya menjalankan pernyataan yang meminta pembaruan statistik dari Plan Explorer. Itu mungkin tidak akan sering terjadi di lingkungan produksi Anda, tetapi Anda mungkin melihat ini saat melakukan pengujian (karena semoga pengujian Anda tidak hanya melibatkan menjalankan kueri SELECT, tetapi juga melibatkan kueri INSERT/UPDATE/DELETE seperti yang Anda lakukan lihat dalam beban kerja normal). Namun, jika Anda memantau lingkungan Anda dengan alat seperti SQL Sentry, Anda mungkin melihat pembaruan ini di SQL Teratas selama melebihi ambang batas pengumpulan SQL Teratas. SQL Sentry memiliki ambang default yang harus dilampaui kueri sebelum ditangkap sebagai Top SQL (misalnya durasi harus melebihi lima (5) detik), tetapi Anda dapat mengubahnya dan menambahkan ambang batas lain seperti pembacaan. Dalam contoh ini, hanya untuk tujuan pengujian , saya mengubah ambang batas durasi minimum SQL Top saya menjadi 10 milidetik dan ambang batas baca saya menjadi 500, dan SQL Sentry dapat menangkap beberapa pembaruan statistik:


Pembaruan statistik ditangkap oleh SQL Sentry

Meskipun demikian, apakah pemantauan dapat menangkap peristiwa ini pada akhirnya akan bergantung pada sumber daya sistem dan jumlah data yang harus dibaca untuk memperbarui statistik. Pembaruan statistik Anda tidak boleh melebihi ambang batas ini, jadi Anda mungkin harus melakukan penggalian lebih proaktif untuk menemukannya.

Ringkasan

Saya selalu mendorong DBA untuk mengelola statistik secara proaktif – yang berarti ada pekerjaan untuk memperbarui statistik secara teratur. Namun, bahkan jika pekerjaan itu berjalan setiap malam (yang saya tidak selalu rekomendasikan), masih sangat mungkin bahwa pembaruan statistik terjadi secara otomatis sepanjang hari, karena beberapa tabel lebih tidak stabil daripada yang lain dan memiliki jumlah modifikasi yang tinggi. Ini tidak normal, dan tergantung pada ukuran tabel dan jumlah modifikasi, pembaruan otomatis mungkin tidak mengganggu kueri pengguna secara signifikan. Tapi satu-satunya cara untuk mengetahuinya adalah dengan memantau pembaruan tersebut – baik Anda menggunakan alat bawaan atau alat pihak ketiga – sehingga Anda dapat mengantisipasi potensi masalah dan mengatasinya sebelum meningkat.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tutorial data:Menggunakan Fungsi Jendela

  2. Memahami Dukungan Java untuk Kegigihan dengan JPA

  3. Menggunakan DBCC CLOENDATABASE dan Query Store untuk Pengujian

  4. Jenis Perintah SQL

  5. SQL, Menangani sel kosong