Saya telah menyimpan prosedur yang secara gila-gilaan setiap kali dipanggil dari aplikasi web.
Saya menyalakan Sql Profiler dan menelusuri panggilan waktu itu dan akhirnya menemukan hal-hal ini:
- Ketika menjalankan pernyataan dari dalam MS SQL Management Studio, dengan argumen yang sama (pada kenyataannya, saya menyalin panggilan prosedur dari jejak profil sql dan menjalankannya): Ini selesai dalam rata-rata 5 ~ 6 detik.
- Tetapi ketika dipanggil dari aplikasi web, dibutuhkan lebih dari 30 detik (dalam jejak) sehingga halaman web saya benar-benar habis waktu itu.
Terlepas dari kenyataan bahwa aplikasi web saya memiliki pengguna sendiri, semuanya sama (database, koneksi, server yang sama, dll.) Saya juga mencoba menjalankan kueri langsung di studio dengan pengguna aplikasi web dan tidak memakan waktu lebih dari 6 detik.
Bagaimana cara mengetahui apa yang terjadi?
Saya berasumsi itu tidak ada hubungannya dengan fakta bahwa kami menggunakan BLL> DAL layers atau adaptor Tabel karena jejaknya dengan jelas menunjukkan penundaan dalam prosedur sebenarnya. Hanya itu yang bisa saya pikirkan.
EDIT Saya menemukan di tautan ini bahwa ADO.NET disetel ARITHABORT
ke true - yang baik untuk sebagian besar waktu tetapi kadang-kadang ini terjadi, dan solusi yang disarankan adalah menambahkan with recompile
opsi ke proc yang disimpan. Dalam kasus saya, itu tidak berfungsi tetapi saya curiga itu adalah sesuatu yang sangat mirip dengan ini. Ada yang tahu apa lagi yang dilakukan ADO.NET atau di mana saya dapat menemukan spesifikasinya?
sumber
Jawaban:
Saya pernah mengalami masalah serupa di masa lalu, jadi saya ingin melihat resolusi untuk pertanyaan ini. Komentar Aaron Bertrand pada OP menyebabkan Query time out ketika dieksekusi dari web, tetapi super cepat ketika dieksekusi dari SSMS , dan meskipun pertanyaannya bukan duplikat, jawabannya mungkin berlaku untuk situasi Anda.
Intinya, sepertinya SQL Server mungkin memiliki rencana eksekusi cache yang rusak. Anda mencapai rencana yang buruk dengan server web Anda, tetapi SSMS mendarat di paket yang berbeda karena ada pengaturan yang berbeda pada bendera ARITHABORT (yang sebaliknya tidak akan berdampak pada kueri / penyimpanan khusus Anda).
Lihat ADO.NET memanggil Prosedur Tersimpan T-SQL menyebabkan SqlTimeoutException untuk contoh lain, dengan penjelasan dan resolusi yang lebih lengkap.
sumber
DBCC DROPCLEANBUFFERS
danDBCC FREEPROCCACHE
lakukan triknya! Saya menduga rencana eksekusi itu entah bagaimana rusak atau tidak diperbarui. Saya ragu itu perbaikan permanen, jika bisa korup sekali, bisa melakukannya lagi. Jadi saya masih mencari penyebab yang masuk akal. Karena aplikasi web sudah kembali berfungsi, saya tidak perlu merasakan tekanan. Terimakasih banyak.OPTIMIZE FOR
atauOPTION(Recompile)
meminta petunjuk pada kueri yang menyebabkan masalah. Artikel ini membahas masalah tersebut secara mendalam. Jika Entity Framework menghasilkan kueri Anda, posting ini tampaknya menyediakan cara untuk menambahkan petunjuk kueri ke kueri Anda.Saya juga mengalami bahwa kueri berjalan lambat dari web dan cepat di SSMS dan saya akhirnya menemukan bahwa masalahnya adalah sesuatu yang disebut parameter sniffing.
Perbaikan bagi saya adalah mengubah semua parameter yang digunakan di sproc ke variabel lokal.
misalnya. perubahan:
untuk:
Kelihatannya aneh, tapi itu memperbaiki masalah saya.
sumber
Bukan untuk mengirim spam, tetapi sebagai solusi yang semoga bermanfaat bagi orang lain, sistem kami mengalami tingkat waktu tunggu yang tinggi.
Saya mencoba mengatur prosedur yang disimpan untuk dikompilasi ulang dengan menggunakan
sp_recompile
dan ini menyelesaikan masalah untuk satu SP.Pada akhirnya ada lebih banyak SP yang time-out, banyak di antaranya belum pernah melakukannya sebelumnya, dengan menggunakan
DBCC DROPCLEANBUFFERS
danDBBC FREEPROCCACHE
tingkat insiden timeout telah turun drastis secara signifikan - masih ada kejadian yang terisolasi, beberapa di mana saya menduga regenerasi rencana sedang berlangsung sementara, dan beberapa di mana SPs benar-benar berkinerja buruk dan perlu evaluasi ulang.sumber
DBCC DROPCLEANBUFFERS
danDBCC FREEPROCCACHE
tidak ada bedanya.Mungkinkah beberapa panggilan DB lain yang dilakukan sebelum aplikasi web memanggil SP tetap membuka transaksi? Itu bisa menjadi alasan SP ini menunggu saat dipanggil oleh aplikasi web. Saya katakan isolasi panggilan di aplikasi web (letakkan di halaman baru) untuk memastikan bahwa beberapa tindakan sebelumnya di aplikasi web menyebabkan masalah ini.
sumber
Cukup mengompilasi ulang prosedur yang tersimpan (fungsi tabel dalam kasus saya) berhasil untuk saya
sumber
seperti @Zane mengatakan itu bisa jadi karena parameter sniffing. Saya mengalami perilaku yang sama dan saya melihat rencana pelaksanaan prosedur dan semua pernyataan sp berturut-turut (menyalin semua pernyataan dari prosedur, menyatakan parameter sebagai variabel dan memberikan nilai yang sama untuk variabel sebagai parameternya). Namun rencana eksekusi terlihat sangat berbeda. Eksekusi sp membutuhkan waktu 3-4 detik dan pernyataan berturut-turut dengan nilai yang persis sama langsung dikembalikan.
Setelah googling beberapa saya menemukan bacaan menarik tentang perilaku itu: Lambat dalam Aplikasi, Cepat di SSMS?
Masalahnya adalah saya memiliki parameter yang dapat dibiarkan kosong dan jika dikirimkan sebagai null, parameter tersebut akan diinisialisasi dengan nilai default.
Setelah saya mengubahnya menjadi
itu bekerja seperti pesona lagi.
sumber