Pengantar
Pengoptimal kueri SQL Server menggunakan statistik selama kompilasi kueri untuk membantu menentukan rencana kueri yang optimal. Secara default, jika pengoptimal melihat statistik kedaluwarsa karena terlalu banyak perubahan pada tabel, pengoptimal akan segera memperbarui statistik sebelum kompilasi kueri dapat dilanjutkan (hanya statistik yang diperlukan, tidak semua statistik untuk tabel) .
Perhatikan bahwa "terlalu banyak" tidak spesifik karena bervariasi menurut versi dan apakah tanda pelacakan 2371 diaktifkan – lihat bagian AUTO_UPDATE_STATISTICS halaman ini untuk detailnya.
Masalah Dengan Pembaruan Statistik Sinkron
Memperbarui statistik secara sinkron sebelum kompilasi jelas menimbulkan penundaan dan membuat kueri membutuhkan waktu lebih lama untuk dikompilasi dan dijalankan. Besar kecilnya delay tergantung pada beberapa faktor, antara lain:
- Berapa banyak tabel yang terlibat dalam kueri yang telah mencapai ambang batas “terlalu banyak perubahan”
- Berapa banyak statistik untuk setiap tabel tersebut yang harus diperbarui karena diperlukan untuk kompilasi
- Berapa banyak baris dalam tabel yang terlibat
- Opsi yang ditentukan saat setiap statistik dibuat (mis., FULLSCAN dan PERSIST_SAMPLE_PERCENT=ON)
Jadi, mungkin ada penundaan yang tampaknya acak, yang mungkin menyebabkan masalah dalam beberapa skenario, terutama jika aplikasi memiliki set waktu tunggu kueri yang sangat rendah.
Menghindari Pembaruan Statistik Sinkron
Ada berbagai cara untuk menghindari pembaruan statistik sinkron, seperti:
- Menyetel AUTO_UPDATE_STATISTICS ke OFF, yang menonaktifkan semua pembaruan otomatis dan berarti Anda harus melakukan pemeliharaan statistik Anda sendiri untuk menghindari kemungkinan rencana kueri yang kurang optimal dari statistik yang kedaluwarsa.
- Menyetel AUTO_UPDATE_STATISTICS_ASYNC ke AKTIF, jadi ketika pengoptimal melihat statistik perlu diperbarui, ia melanjutkan kompilasi, dan tugas latar belakang memperbarui statistik sedikit kemudian. Ini hanya berfungsi jika Anda juga menyetel AUTO_UPDATE_STATISTICS ke AKTIF.
- Lakukan pemeliharaan statistik secara rutin, sehingga pembaruan statistik sinkron atau asinkron otomatis tidak terjadi sama sekali.
Ada banyak perdebatan di komunitas SQL Server seputar apakah akan mengaktifkan pembaruan statistik asinkron. Saya bertanya kepada istri saya yang cantik, Kimberly L. Tripp, apa pendapatnya, dan dia selalu menyarankan untuk mengaktifkannya, dan dia lebih melupakan statistik daripada yang pernah saya ketahui, jadi saya percaya padanya.
Melacak Pembaruan Statistik Sinkron
Tidak pernah ada cara yang jelas untuk mengetahui apakah kueri membutuhkan waktu lama karena menunggu pembaruan statistik sinkron. Anda dapat mengetahui *setelah* pembaruan statistik selesai jika Anda memiliki sesi Acara yang Diperpanjang yang sudah berjalan sambil menonton statistik_otomatis acara dan pemfilteran pada async kolom disetel ke 0. Namun, kolom tersebut dalam output peristiwa hanya ditambahkan di SQL Server 2017, dan Anda juga harus mengonfigurasi tindakan yang menangkap sesuatu untuk mengidentifikasi kueri yang terlibat.
Sekarang di SQL Server 2019, ada tipe tunggu WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE , dan pada pandangan pertama sepertinya itu akan dengan mudah memungkinkan Anda untuk melihat apakah kueri sedang menunggu pembaruan statistik sinkron dengan hanya melihat di sys.dm_os_waiting_tasks untuk melihat apa kueri saat ini menunggu.
Sayangnya, bukan itu masalahnya.
Istilah "menunggu" agak menyesatkan di sini karena dalam hal ini utasnya tidak benar-benar menunggu. Jenis menunggu baru ini adalah contoh dari apa yang disebut menunggu "preemptive", di mana utas beralih ke mode di mana ia tetap berada di prosesor hingga selesai bekerja. Penantian paling awal adalah saat utas melakukan panggilan di luar SQL Server (mis., untuk mendapatkan informasi keamanan dari Pengontrol Domain), tetapi terkadang utas melakukan sesuatu di dalam SQL Server dan perlu menyelesaikannya sebelum berpotensi dipaksa untuk menghasilkan prosesor karena kuantum utas 4msnya telah kedaluwarsa. Tak satu pun dari hal-hal itu yang terjadi di sini. Dalam hal ini, utas mencatat awal dari menunggu preemptive dengan jenis menunggu baru dan kemudian melakukan pembaruan statistik, mungkin menimbulkan menunggu *nyata* lainnya seperti PAGEIOLATCH_SH di sepanjang jalan. Baru setelah pembaruan statistik selesai, masa tunggu preemtif berakhir dan diperhitungkan dalam metrik statistik tunggu.
Mengapa ini masalah besar? Nah, DMV sys.dm_os_waiting_tasks menunjukkan jenis tunggu untuk semua utas yang *benar-benar* menunggu, yaitu, pada daftar tugas menunggu penjadwal, jadi jika utas pembaruan statistik sinkron tidak menunggu WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE, jenis tunggu itu tidak akan muncul di output DMV. Jenis tunggu yang baru tidak dapat digunakan untuk melihat apakah kueri sedang menunggu pembaruan statistik.
Anda dapat dengan mudah membuktikannya sendiri dengan melakukan hal berikut:
- Buat tabel dengan beberapa ratus ribu baris
- Buat statistik pada kolom tabel, dan tentukan FULLSCAN dan PERSIST_SAMPLE_PERCENT =ON sebagai opsi, memaksa seluruh tabel untuk dibaca setiap kali statistik diperbarui
- Perbarui dua puluh ribu baris
- Periksa database dan jalankan DBCC DROPCLEANBUFFERS
- Lakukan pernyataan SELECT dengan klausa WHERE pada kolom dengan statistik yang Anda buat
- Lihat di sys.dm_os_waiting_tasks DMV untuk ID sesi SELECT, dan Anda akan melihat kemungkinan menunggu PAGEIOLATCH_SH saat pembaruan statistik membaca tabel
Terlepas dari kekecewaan itu, ada trik untuk dapat melihat apakah kueri sedang menunggu pembaruan statistik sinkron. Saat pembaruan statistik terjadi, perintah yang disebut STATMAN berjalan, dan Anda dapat melihatnya terjadi di output dari sys.dm_exec_requests :status akan "ditangguhkan" (meskipun utas sedang berjalan, seperti yang saya jelaskan di atas), dan perintah akan menjadi “PILIH (STATMAN).”
Apa Gunanya Jenis Tunggu Baru?
Meskipun jenis tunggu yang baru tidak dapat digunakan sebagai cara langsung untuk memberi tahu bahwa kueri sedang menunggu pembaruan statistik sinkron, jika muncul dalam analisis statistik tunggu reguler Anda, Anda tahu bahwa beberapa kueri dalam beban kerja mungkin mengalami penundaan ini . Tapi itu tentang batas kegunaannya sejauh yang saya ketahui. Kecuali jika waktu tunggu rata-rata muncul sebagai persentase yang mengkhawatirkan dari waktu eksekusi kueri rata-rata Anda atau Anda terus-menerus menunggu selama periode waktu yang kecil untuk memungkinkan analisis yang tepat, Anda tidak tahu pasti apakah ada masalah.
Ini adalah jenis menunggu di mana waktu tunggu dapat sangat bervariasi, tergantung pada faktor yang saya sebutkan sebelumnya. Oleh karena itu, saya hanya akan menggunakan kehadiran jenis tunggu ini untuk diberi tahu tentang potensi masalah, dan saya ingin menerapkan sesi Acara yang Diperpanjang seperti yang dijelaskan di atas untuk menangkap contoh pembaruan statistik sinkron untuk melihat apakah durasinya cukup lama untuk mendapatkan manfaat. mengambil beberapa tindakan korektif.
Ringkasan
Saya tidak yakin bahwa penambahan jenis tunggu WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE akan mengubah apakah orang mengonfigurasi pembaruan statistik asinkron atau hanya melakukan semua pemeliharaan statistik sendiri, tetapi setidaknya sekarang Anda dapat mengetahui apakah kueri sedang menunggu statistik sinkron memperbarui dan mengambil tindakan lebih lanjut.
Sampai jumpa lagi, selamat memecahkan masalah kinerja!