Dua hari Rabu terakhir, kami telah menyelenggarakan seri webinar dua bagian yang membahas masalah sensitivitas parameter:
- Prosedur, Parameter, Masalah Tersimpan…
Kimberly L. Tripp dan Aaron Bertrand
24 Januari
Ketinggalan? Daftar untuk menontonnya sekarang! - Menangani Pengendapan Parameter Menggunakan SentryOne
Aaron Bertrand, Kimberly L. Tripp, dan Andy Mallon
31 Januari
Ketinggalan? Tonton sekarang!
Beberapa pertanyaan muncul selama kedua webinar, dan saya pikir saya akan mengkompilasinya dan menjawabnya di sini (beberapa jawaban datang dari Andy selama webinar).
Dalam masalah yang kami lihat baru-baru ini, kami melihat rencana dikeluarkan dari cache dengan sangat cepat. Kami tidak melakukan apa pun yang Anda jelaskan (
DBCC FREEPROCCACHE
dll.); dapatkah tekanan memori juga menyebabkan hal ini terjadi?
Ya, tekanan memori bisa menjadi faktor (lihat posting ini), dan saya tahu ada beberapa penyelidikan potensi masalah dengan manajemen memori SQL Server dalam hal ini juga.
Dari seorang peserta:"Bukan pertanyaan, tetapi komentar kepada pengguna yang menanyakan tentang berapa kali cache rencananya dikosongkan. Kami juga memilikinya dan, memang, itu adalah tekanan memori. Kami memiliki memori server maks yang salah dikonfigurasi, yaitu diperbaiki menggunakan rumus yang disebutkan di sini, lalu kami menjalankan prosedur dari artikel ini setiap 10 menit (kami memiliki banyak SQL dinamis, hanya digunakan satu kali)."
Bagaimana jika Anda menggunakan
OR
di klausa where alih-alihAND
, apakah masalah akan tetap ada?
Biasanya jika Anda menggunakan
OR
dalam jenis pola ini, Anda akan mendapatkan semua baris setiap saat, kecuali setiap parameter diisi dengan nilai yang memfilter baris. Ini mengubah semantik kueri dari "semua hal ini harus benar" menjadi "salah satu dari hal ini bisa benar." Namun, rencana yang dikompilasi untuk set parameter pertama akan tetap disimpan dalam cache dan dipertahankan untuk eksekusi di masa mendatang, baik klausa Anda menggunakanAND
atauOR
.
Apakah itu
1=1
menandai pendekatan yang baik? Bukankah lebih baik hanya menambahkan parameter yang disediakan dan oleh karena itu hindari1=1
ugly yang jelek ?
1 = 1
hampir diabaikan oleh SQL Server, tetapi memungkinkan semua klausa bersyarat ditambahkan denganAND
sehingga Anda tidak perlu memperlakukan yang *pertama* secara berbeda. Ini alternatifnya:SET @IncludedWhereClauseYet bit = 0; SET @sql = N'SELECT cols FROM dbo.Table'; IF @param1 IS NOT NULL BEGIN IF @IncludedWhereClauseYet = 0 BEGIN SET @sql += N' WHERE '; SET @IncludedWhereClauseYet = 1; END ELSE BEGIN SET @sql += N' AND '; END SET @sql += N' @param1 = @param1'; END IF @param2 IS NOT NULL BEGIN IF @IncludedWhereClauseYet = 0 ... END ...
1=1
memungkinkan Anda untuk menyederhanakan, dengan membiarkan Anda selalu mengawali klausa apa pun denganAND
. Kode di atas menjadi:SET @sql = N'SELECT cols FROM dbo.Table WHERE 1 = 1'; IF @param1 IS NOT NULL BEGIN SET @sql += N' AND @param1 = @param1'; END IF @param2 IS NOT NULL BEGIN SET @sql += N' AND @param2 = @param2'; ENDAnda mungkin dapat menggunakan klausa awal yang berbeda untuk menghindari semua persyaratan, seperti
WHERE PrimaryKey > 0
atauWHERE PrimaryKey IS NOT NULL
, lalu setiap klausa berikutnya dapat dimulai denganAND
. Tapi1 = 1
, meskipun jelek, tidak berbahaya, dan IMHO tidak kalah jeleknya dengan menambahkan klausa *nyata* tetapi tidak berarti, kecuali bahwa klausa *nyata* dapat memengaruhi rencana.Ingatlah bahwa ketika Anda membuat kode T-SQL dengan T-SQL, Anda memiliki dua aspek "jelek" untuk dipikirkan – terkadang Anda akan memecahkan masalah kode di atas, dan terkadang Anda akan memecahkan masalah kueri yang keluar dari dia. Berhati-hatilah dalam mengorbankan satu demi yang lain.
APA?! Saya benar-benar merindukan itu ...
WITH RECOMPILE
. Saya pikir itu mengosongkan rencananya, tetapi itu membiarkannya hanya untuk eksekusi ini… itu sangat penting untuk diketahui!
Pastikan Anda juga mengetahui kerugiannya.
Lihat postingan hebat dari Paul White ini.
Apakah
OPTION OPTIMIZE FOR @parametername UNKNOWN
tidak lagi disukai di versi SQL yang lebih baru?
Saya tidak berpikir itu lebih baik atau lebih buruk dalam versi modern daripada ketika pertama kali diperkenalkan di SQL Server 2008. Sejauh yang saya tahu, bahkan dengan semua perubahan pada pengoptimal dan penaksir kardinalitas, bit itu masih berperilaku dengan cara yang sama.
Apakah ada beban di server, jika saya mengaktifkan pengambilan statistik Prosedur dan statistik Kueri di SentryOne?
Kumpulan statistik Prosedur &Kueri harus diaktifkan secara default. Semua pengumpulan data dikenakan biaya, tetapi SQL Sentry cukup berhati-hati tentang berapa banyak biaya yang dikeluarkan untuk pengumpulan.
Pencarian di RS tidak menggunakannya sebagai predikat residual, itu mencari sesuatu yang lain yang tidak bisa saya lihat.
Terima kasih, saya akan meninjau kembali contoh itu, dan blog tentang demo secara terpisah, memastikan untuk menyertakan detail relevan yang tidak terlihat dari diagram rencana saja.
Benarkah menambahkan beberapa kolom diperlukan sebagai
INCLUDE
s tidak benar-benar membuat indeks lebih efektif karena pencarian kunci tidak akan dihilangkan? Menurut saya persentasenya tidak akan berubah kecuali Anda benar-benar menghilangkan pencarian kunci.
Tegasnya, ya, itu benar. Kueri asli adalah contoh buruk yang terpenting, menggunakan
SELECT *
dan indeks kehilangan jumlah kolom yang tidak ada harapan. Poin yang saya coba sampaikan adalah bahwa tab Analisis Indeks mendorong Anda untuk (a) meningkatkan kueri dan (b) membuat sampul indeks. Skor ada untuk menarik Anda melakukan salah satu atau keduanya – jika Anda mengubah kueri sehingga Anda membutuhkan lebih sedikit kolom, indeks juga lebih dekat untuk mencakup kueri. Jika Anda akan membuat indeks penutup baru yang terpisah, Anda juga memiliki informasi tentang kolom mana yang diperlukan untuk mencakup kueri khusus ini. Secara teknis, Anda benar, menambahkan satu kolom penyertaan tetapi masih memerlukan pencarian untuk 4 lainnya tidak akan membuat kueri khusus ini berkinerja lebih baik, dan tidak akan membuat indeks lebih baik, tetapi ini menunjukkan bahwa Anda' kembali semakin dekat. Harapannya adalah Anda tidak berhenti hanya menambahkan satu kolom include dan mengabaikan sisanya. Kami tidak tahu kapan Anda akan berhenti, jadi saya tidak tahu ada solusi sempurna – kami tentu tidak ingin mengecewakan pengguna membuat indeks mereka lebih cocok untuk kueri mereka.
Mengapa kita melihat kueri menggunakan parameter nama depan dan parameter nama belakang diringkas di bawah pernyataan yang hanya menggunakan parameter nama belakang?
PERBARUI: Ini disengaja. Pengelompokan di bawah Tampilkan Total mengelompokkan prosedur yang sama yang disebut dengan semua kombinasi parameter yang berbeda. Jadi Anda dapat menggunakannya terlebih dahulu untuk menentukan parameter mana yang cenderung menyebabkan kinerja terburuk, kemudian di dalamnya, telusuri apakah ada data yang miring atau tidak. Parameter yang mengarah ke pencarian terhadap kolom yang tidak diindeks, misalnya, mungkin akan naik ke atas dengan cukup andal, dan Anda dapat melihatnya dalam kombinasi dengan parameter lain yang diteruskan dan juga dibandingkan dengan semua panggilan di mana parameter itu tidak ' t lulus.
Setelah mengatakan semua itu, kita akan melihat untuk menyempurnakan perilaku pengelompokan ini saat kita menyelesaikan perubahan saat ini dalam penerbangan untuk layar SQL Teratas.
Apakah ada dokumentasi tentang cara menggunakan panduan rencana? Saat ini saya tidak tahu bagaimana melakukannya.
Ini adalah hal lain yang ingin saya bahas di blog, tetapi Microsoft memiliki beberapa topik di sini untuk sementara (dan periksa semua tautan terkait di bilah sisi).
Apakah saya perlu mengaktifkan sesuatu untuk mendapatkan Bagan Riwayat Kueri?
Tidak, ini harus diaktifkan pada semua versi modern aplikasi klien SentryOne. Jika Anda tidak melihatnya, coba
Tools > Reset Layout
; jika tidak berhasil, hubungi [email protected].
Apakah ada kasus ketika memaksakan rencana bagus yang terakhir diketahui menggunakan Query Store ketika regresi rencana ditemukan sebagai ide yang buruk? Apakah itu cenderung menyembunyikan masalah yang lebih baik ditangani dengan mengubah pernyataan seperti yang Anda tunjukkan?
Memaksa rencana seringkali merupakan pilihan terakhir, dan saya cenderung mencadangkannya untuk kasus-kasus di mana Anda benar-benar tidak dapat memperbaiki pernyataan (atau mengubah indeks). Memaksakan sebuah rencana selalu dapat mengarah pada perilaku yang salah, karena pilihan itu tetaplah manusia, dan Anda bisa membuatnya berdasarkan info buruk. Regresi mungkin karena perubahan rencana, tetapi jika Anda menilainya sebagai regresi karena runtime lebih lama, sudahkah Anda menyelidiki kemungkinan alasan lain? Misalnya, katakanlah sistem di-boot ulang atau ada failover, dan mendapat rencana baru karena yang lama digusur, dan mungkin sementara itu statistik juga berubah, tetapi sekarang kueri berjalan lebih lama bukan karena rencana itu lebih buruk tetapi bukan karena buffer kosong. Jadi ya, saya tentu tidak menyarankan memaksakan rencana pada setiap regresi.
SentryOne tidak selalu menangkap data atau parameter setiap saat, jadi saya tidak memiliki informasi yang cukup. Bagaimana cara memastikan SentryOne menangkap parameter dan rencana eksekusi setiap saat?
Anda benar-benar tidak bisa karena ini semua tergantung pada bagaimana kueri Anda dieksekusi, bagaimana kami menangkapnya, dan seberapa cepat mereka dijalankan. Seringkali kueri Anda tidak berjalan cukup lama untuk ditangkap sepenuhnya, dan kami harus mengandalkan tampilan statistik kueri/prosedur gabungan SQL Server, yang tidak mengumpulkan informasi parameter. Anda dapat mengubah setelan pengumpulan untuk Sumber SQL Teratas untuk menangkap lebih banyak dan pada interval yang lebih sering, tetapi Anda perlu menyeimbangkan jumlah data yang Anda kumpulkan dengan seberapa banyak informasi tambahan yang dibelinya untuk Anda.
Dapatkah saya meminta informasi sehingga saya dapat mengotomatisasi dan membuat laporan?
Kami tidak memiliki apa pun untuk Anda lakukan, tetapi izinkan saya membawanya kembali ke tim dan melihat opsi apa yang bisa kami buat. Satu hal yang saya mainkan untuk webinar ini adalah membangun Kondisi Penasehat untuk menangkap jenis regresi yang kami cari, tetapi waktu menjadi faktor.
Bagaimana kami memutuskan kapan harus menggunakan
OPTION (RECOMPILE)
, karena setiap hari kami mendapatkan paket yang berbeda untuk parameter yang berbeda?
Saya akan mengatakan mulai dengan kueri yang paling berfluktuasi dengan sensitivitas parameter. Jika saya memiliki kueri yang terkadang membutuhkan waktu 2 detik tetapi terkadang membutuhkan waktu 30, dan kueri lain yang berkisar antara 4 detik hingga 6 detik,
saya akan fokus pada yang pertama.
Mana yang lebih baik untuk digunakan,
OPTION (RECOMPILE)
atauQUERYTRACEON
, dalam kasus sniffing parameter.
Saya lebih suka
OPTION (RECOMPILE)
karena dua alasan. Satu, itu mendokumentasikan diri sendiri; tidak ada yang membaca kode akan bertanya-tanya apa yang dilakukannya, tetapi tidak semua orang yang membaca kode akan mengingat nomor TF seperti 4136. Dua, tidak memerlukan izin yang lebih tinggi – coba gunakanQUERYTRACEON
sebagai prajurit.
Apakah mungkin untuk memperingatkan atau melaporkan prosedur yang memakan waktu lebih lama dari biasanya? Paling tertarik dengan prosedur berhitung tinggi.
Tentu saja, Anda dapat menggunakan Kondisi Penasehat, tetapi ini bisa menjadi sedikit rumit karena – untuk prosedur yang bahkan terkadang berjalan di bawah ambang batas pengumpulan – Anda perlu membandingkan snapshot dari statistik prosedur DMV. Saya telah menambahkan pengingat ke blog tentang yang satu ini juga, karena ini adalah sesuatu yang saya telah membantu pelanggan menerapkannya di masa lalu.
Microsoft menjadikan Penyetelan Otomatis sebagai default untuk Azure SQL Database, termasuk koreksi paket otomatis. Apakah itu ide yang bagus untuk Anda?
Saya akan memberikan penilaian sampai saya (atau beberapa pelanggan) bermain-main dengannya. Memutuskan bagaimana menyetel cukup menantang bagi manusia; perangkat lunak penulisan manusia untuk menyetel Anda tampaknya setidaknya sama menantangnya, jika tidak lebih dari itu. Ketika Andy melihat pertanyaan ini, dia mengatakan kepada saya bahwa itu mengingatkannya pada SQL Server 2000 – promosi pemasarannya adalah bahwa hal itu sangat self-tuning sehingga kita tidak membutuhkan DBA lagi. Klaim itu belum cukup umur.
Mampu memilih dua titik pada bagan Riwayat Kueri dan membandingkannya akan menyenangkan.
Saya setuju.
Terus ikuti perkembangannya.