Mengapa permintaan saya tiba-tiba lebih lambat dari kemarin?

76

[Salam]

(periksa satu)

[ ] Well trained professional, [ ] Casual reader, [ ] Hapless wanderer,

Saya punya (centang semua yang berlaku)

[ ] query [ ] stored procedure [ ] database thing maybe  

yang berjalan dengan baik (jika ada)

[ ] yesterday [ ] in recent memory [ ] at some point 

tapi tiba-tiba lebih lambat sekarang.

Saya sudah memeriksa untuk memastikan itu tidak diblokir, dan itu bukan korban dari tugas pemeliharaan, laporan, atau proses band lain yang berjalan lama.

Apa masalahnya, apa yang harus saya lakukan, dan informasi apa yang dapat saya berikan untuk mendapatkan bantuan?

[*Insert appropriate closing remarks*]
Erik Darling
sumber

Jawaban:

88

Sayang [namamu di sini]!

Oh tidak, maaf mendengarnya! Mari kita mulai dengan beberapa dasar untuk memperbaiki Anda dalam sekejap.

Hal yang Anda temui disebut Parameter Sniffing

Itu jalan keluar masalah aneh aneh. Nama itu bergulung langsung dari lidah. Seperti kata Jerman untuk tupai.

Dan biasanya temanmu.

Ketika kueri mengenai server Anda, sebuah rencana harus dikompilasi. Untuk menghemat waktu dan sumber daya nanti, rencana eksekusi di-cache berdasarkan pada perkiraan baris yang akan menyebabkan kode Anda diproses dan dikembalikan.

Cara termudah untuk menggambarkan ini menjadi buruk adalah dengan membayangkan prosedur tersimpan yang perlu menghitung hal-hal dari dua populasi yang miring.

Sebagai contoh:

  • Orang-orang yang mengenakan kemeja CrossFit yang tidak terluka: Nol

  • Orang-orang yang memakai kemeja CrossFit yang meringis ketika mereka meringis: Semua

Jelas, satu eksekusi kode itu harus melakukan lebih banyak pekerjaan daripada yang lain, dan rencana kueri yang ingin Anda lakukan dengan jumlah pekerjaan yang sama sekali berbeda akan terlihat sangat berbeda.

Apa yang saya hadapi?

Ini adalah masalah yang benar-benar sulit untuk ditemukan, diuji, dan diperbaiki.

  • Sulit ditemukan karena itu tidak terjadi secara konsisten
  • Sulit untuk menguji karena Anda perlu tahu parameter mana yang menyebabkan rencana berbeda
  • Sulit untuk memperbaikinya karena kadang-kadang membutuhkan pencarian dan penyetelan indeks
  • Sulit untuk diperbaiki karena Anda mungkin tidak dapat mengubah kueri atau indeks
  • Sulit untuk diperbaiki karena meskipun Anda mengubah kueri atau indeks, itu mungkin masih kembali

Perbaikan cepat

Terkadang, yang Anda butuhkan hanyalah sedikit kejelasan. Atau lebih tepatnya, cache paket Anda.

Jika itu prosedur yang tersimpan

Coba jalankan EXEC sys.sp_recompile @objname = N'schema.procname'. Itu akan menyebabkan prosedur mengkompilasi ulang rencana baru saat dijalankan berikutnya.

Apa yang tidak akan diperbaiki ini:

  • Proses saat ini menjalankannya.

Apa ini tidak menjamin:

  • Proses selanjutnya yang berjalan setelah kompilasi akan menggunakan parameter yang memberi Anda rencana yang baik.

Anda juga bisa menunjuk sp_recompilepada tabel atau tampilan, tetapi diperingatkan sebelumnya bahwa semua kode yang menyentuh tabel atau tampilan itu akan dikompilasi ulang. Ini bisa membuat masalahnya jauh lebih sulit.

Jika itu kueri parameterisasi

Pekerjaan Anda sedikit lebih sulit. Anda harus melacak SQL Handle. Anda tidak ingin membebaskan seluruh cache rencana - seperti menggunakan sp_recompiletabel atau tampilan, Anda dapat memicu (ha ha ha) sejumlah konsekuensi yang tidak diinginkan.

Cara termudah untuk mengetahui perintah itu adalah dengan menjalankan sp_BlitzSiapa *! Ada kolom yang disebut "fix parameter sniffing" yang memiliki perintah untuk menghapus satu paket dari cache. Ini memiliki kelemahan yang sama dengan mengkompilasi ulang.

Apa yang tidak akan diperbaiki ini:

  • Proses saat ini menjalankannya.

Apa ini tidak menjamin:

  • Proses selanjutnya yang berjalan setelah kompilasi akan menggunakan parameter yang memberi Anda rencana yang baik.

Saya masih butuh bantuan!

Kita akan membutuhkan hal-hal berikut:

  • Paket permintaan yang bagus, jika memungkinkan
  • Paket kueri yang buruk
  • Parameter yang digunakan
  • Kueri yang dimaksud
  • Tabel dan definisi indeks

Mendapatkan paket kueri dan kueri

Jika kueri berjalan, Anda dapat menggunakan sp_BlitzWho * atau sp_WhoIsActive untuk menangkap kueri yang sedang dieksekusi.

EXEC sp_BlitzWho;

EXEC sp_WhoIsActive @get_plans = 1;

GILA

Jika permintaan saat ini tidak dieksekusi, Anda dapat memeriksanya di cache paket, menggunakan sp_BlitzCache *.

Jika Anda menggunakan SQL Server 2016+, dan mengaktifkan Query Store, Anda dapat menggunakan sp_BlitzQueryStore *.

EXEC dbo.sp_BlitzCache @StoredProcName = 'Your Mom';

EXEC dbo.sp_BlitzQueryStore @StoredProcName = 'Your Mom';

Ini akan membantu Anda melacak versi tersimpan dari Prosedur tersimpan Anda. Jika hanya kode parameter, pencarian Anda sedikit lebih sulit. Ini mungkin membantu, meskipun:

EXEC dbo.sp_BlitzCache @QueryFilter = 'statement';

Anda akan melihat keluaran yang hampir serupa dari semua itu. Sekali lagi, paket permintaan yang mengundang kolom klik biru yang keren adalah teman Anda.

GILA

Cara termudah untuk membagikan paket menggunakan Paste Paket *, atau membuang XML ke pastebin. Untuk mendapatkan itu, klik salah satu kolom yang mengundang klik berwarna biru. Paket kueri Anda akan muncul di tab SSMS baru.

GILA

Jika Anda tidak suka membagikan kode dan kueri perusahaan Anda, Anda dapat menggunakan alat Plan Explorer gratis milik Sentry One untuk menganonimkan paket Anda. Perlu diingat, ini membuat mendapatkan bantuan lebih sulit - kode anonim jauh lebih sulit untuk dibaca dan dipikirkan.

Semua alat yang kita bicarakan ini harus mengembalikan Teks Kueri. Anda tidak perlu melakukan hal lain di sini.

Mendapatkan parameter sedikit lebih sulit. Jika Anda menggunakan Plan Explorer , ada tab di bagian bawah yang mencantumkan semuanya untuk Anda.

GILA

Jika Anda menggunakan sp_BlitzCache *, ada kolom yang dapat diklik yang memberi Anda pernyataan eksekusi untuk prosedur tersimpan.

GILA

Mendapatkan tabel dan definisi indeks

Anda dapat dengan mudah mengklik SSMS untuk membuat skrip.

GILA

Jika Anda ingin mendapatkan semuanya dalam satu kesempatan, sp_BlitzIndex * dapat membantu jika Anda mengarahkannya langsung ke sebuah tabel.

EXEC dbo.sp_BlitzIndex @DatabaseName = 'StackOverflow2010',
                       @SchemaName = 'dbo',
                       @TableName = 'Users';

Ini akan memberi Anda definisi tabel (meskipun bukan sebagai buat pernyataan), dan buat pernyataan untuk semua indeks Anda.

Mengumpulkan dan menambahkan informasi ini ke pertanyaan Anda harus membuat orang cukup informasi untuk membantu, atau mengarahkan Anda ke arah yang benar.

Saya ingin melakukannya sendiri!

Baiklah keren. Aku bahagia untukmu Anda orang gila.

Ada banyak cara orang berpikir mereka "memperbaiki" mengendus parameter:

Tapi ini benar-benar hanya menonaktifkan parameter sniffing dengan cara berbeda. Itu bukan untuk mengatakan bahwa mereka tidak dapat menyelesaikan masalah, mereka hanya tidak benar-benar sampai ke akar permasalahan.

Itu karena sampai ke akar penyebab biasanya agak sulit. Anda harus mencari "rencana masalah kualitas" sial itu.

Dimulai dengan rencana cepat vs lambat, cari perbedaan seperti:

  • Indeks digunakan
  • Gabung pesanan
  • Serial vs Paralel

Cari juga berbagai operator yang membuat kode Anda peka terhadap parameter sniffing:

  • Pencarian
  • Macam-macam
  • Bergabunglah dengan tipe
  • Hibah memori (dan dengan ekstensi, tumpahan)
  • Gulungan

Jangan terlalu larut dalam pencarian vs pemindaian, fragmentasi indeks, atau hal-hal pemujaan yang dilakukan orang.

Biasanya, ada masalah pengindeksan yang cukup mendasar. Terkadang kodenya perlu ditulis ulang.

Jika Anda ingin mempelajari lebih lanjut tentang sniffing parameter:

Jika Anda membaca ini, dan Anda merasa saya melewatkan tautan atau alat yang bermanfaat, tinggalkan komentar. Saya akan melakukan yang terbaik untuk membuat ini tetap terbaru.


Erik Darling
sumber
28

Mengendus parameter bukan satu-satunya penyebab yang mungkin untuk kinerja beragam permintaan. Salah satu alasan umum berikut dapat menunjukkan gejala yang sama:

  1. Distribusi / volume data berubah, melewati titik kritis keputusan pohon pencarian pengoptimal
  2. Indeks / file terfragmentasi
  3. Statistik telah diperbarui / ditambahkan / dijatuhkan atau menjadi basi dan menyesatkan karena perubahan data
  4. Pemanfaatan memori Windows berubah
  5. Log transaksi penuh dan tidak terpotong, menyebabkan ekspansi file fisik berulang
  6. Skema berubah - indeks / tampilan terindeks / kolom / batasan ditambahkan, dimodifikasi atau dijatuhkan, tipe data berubah, dll.
  7. Pengaturan jejak jejak diubah
  8. Pembaruan Windows diterapkan
  9. Pengaturan basis data atau server berubah
  10. Level server CU berubah
  11. Pengaturan sesi aplikasi klien berubah

Butir 6 - 11 dalam daftar ini hanya dapat terjadi setelah beberapa tindakan eksplisit dilakukan. Saya kira Anda bermaksud mengecualikan itu, tetapi berkali-kali orang yang mengalami tantangan, tidak menyadari bahwa orang lain membuat perubahan, dan itu patut diperiksa sebelum Anda memulai jalur membersihkan entri cache rencana.

SQLRaptor
sumber
1
Terima kasih untuk suntingan Paul. @sp_BlitzErik - Bukan maksud saya untuk memberikan saran tentang topik tertentu, hanya untuk meningkatkan kesadaran bahwa topik itu ada, dan mungkin layak untuk dicoba. Ini sama sekali tidak dimaksudkan untuk mengurangi dari jabatan besar Anda. Anda berurusan dengan mengendus parameter secara mendalam, profesional, dan dengan humor yang baik. Saya senang membacanya. Saya hanya ingin memastikan bahwa jika seseorang di sini mengunjungi pos ini, mengikuti judul yang mudah diingat, ia dibuat sadar akan kemungkinan penyebab alternatif. IMHO itu menambah nilai pada posting Anda, tetapi jika Anda masih ingin saya menghapusnya, beri tahu saya.
SQLRaptor
Tidak, tidak sama sekali. Saya tidak pernah meminta seseorang untuk menghapus jawaban yang tidak salah atau berbahaya. Saya masih berpikir Anda bisa menambahkan beberapa detail, tetapi pada akhirnya terserah Anda.
Erik Darling
10

Hanya untuk menambah jawaban yang ada jika mereka tidak membantu, ketika "tiba-tiba" pertanyaan Anda berperilaku berbeda pada hari berikutnya, periksa:

  • Apakah skema untuk tabel yang digunakan berubah sejak terakhir kali? Dalam hal SSMS, Anda dapat mengklik kanan server di Object Explorer dan memilih Reports → Standard Reports → Schema Changes History.
  • Apakah jumlah barang meningkat secara dramatis? Mungkin permintaan Anda jauh lebih lambat ketika ada banyak data di tabel yang digunakan.
  • Apakah orang lain menggunakan database pada saat yang sama dengan Anda? Mungkin memilih slot waktu di mana Anda tidak mengganggu pekerjaan masing-masing.
  • Bagaimana statistik sistem terlihat? Mungkin server berjalan panas dan memperlambat CPU atau hard drive kehabisan ruang atau swap. Mungkin ada masalah perangkat keras lain seperti kebakaran atau banjir di ruang server.
pengguna1306322
sumber
7

Kemungkinan lain adalah bahwa Tim Infrastruktur Anda menggunakan alat-alat seperti vMotion di VMware dan VM yang mendukung instance SQL Anda sedang dipindahkan dengan mulus dari Host ke Host tanpa DBA mengetahuinya.

Ini adalah masalah nyata ketika Infrastruktur Anda kekurangan sumber daya ... Saya mengalami mimpi buruk yang nyata dengannya.

dengan tenang
sumber