Kueri seperti di bawah ini yang dijamin tidak akan mengembalikan baris apa pun, membutuhkan waktu mulai 0 hingga 160 detik di salah satu server kami:
select col1, col2, col3
from tab1
where 0 = 1
Dua minggu lalu, ini terjadi enam kali dalam interval 48 jam. Minggu lalu permintaan yang sama memakan waktu ~ 0 detik. Saya memiliki log SQL aplikasi kita tetapi belum menemukan tersangka. Selain itu, saya pikir 0 / atas mana 0 = 1 jenis kueri tidak pernah mengenai halaman data, jadi harus tahan terhadap kunci data tingkat baris / halaman / tabel? Skema ini tidak tersentuh oleh SQL (dikenal) apa pun.
Karena masalahnya tidak konsisten, dan server berada di bawah beban yang sangat berat, saya ingin memahami teori di balik apa yang terjadi sebelum melampirkan profiler SQL. Kueri lain berjalan tanpa masalah selama penundaan ini. Masalah yang diketahui dalam aplikasi ini adalah tingginya jumlah kueri SQL yang dibuat secara dinamis - sekitar 200k kueri unik dari total 850k (log) kueri selama 48 jam, dapatkah ini menyebabkan masalah seperti ini?
Server menjalankan SQL Server 2005 edisi standar, RAM 96 GB, disk pada SAN dan 4 CPU / 16 core. File dan filegroup basis data dioptimalkan dengan baik dan seharusnya tidak menjadi masalah (tapi kami melihat ini secara terpisah).
Setiap petunjuk di mana mencarinya sangat dihargai.
Sunting: Sempurna! Memutar ulang kueri untuk menambahkan rencana eksekusi, dan butuh 1 menit 35 detik. Berikut rencana eksekusi dan tangkapan layar yang menunjukkan durasi kueri:
Sunting 2: detail waktu statistik untuk putaran kedua. Tampaknya lambat secara konsisten saat ini, jadi kami akan melampirkan profiler dan perfmon:
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 97402 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
sumber
Jawaban:
Tampaknya seolah-olah dengan
... WHERE 0 = 1
klausa bahwa masih akan ada persyaratan untuk maksud shared (IS
) kunci di atas meja. Mari kita buktikan ini:Saya akan memulai dengan membuat tabel tes:
Sekarang saya memiliki tabel pengujian saya, dalam satu sesi (jendela permintaan) saya akan menjalankan yang berikut ini untuk menempatkan
X
kunci ( ) eksklusif padadbo.MyTestTable1
:Saya dapat memverifikasi kunci eksklusif dengan melihat
sys.dm_tran_locks
DMV. Kemudian di sesi lain (jendela permintaan baru) saya melakukan persis apa yang dilakukan permintaan Anda:Pada pandangan pertama saya melihat bahwa itu tidak selesai. Melihat
sys.dm_exec_requests
, saya tahu persis mengapa ini terjadi:Saya dapat melihat di sini bahwa
... WHERE 0 = 1
permintaan saya sedang menungguIS
kunci untuk objek ini (yang diterjemahkan oleh object_iddbo.MyTestTable1
).Saya sama sekali tidak mengatakan bahwa konkurensi adalah masalah Anda , tetapi dari suaranya Anda menunjukkan gejalanya. Contoh di atas adalah untuk membuktikan bahwa Anda tidak dibebaskan dari mengunci dan memblokir bahkan dengan
WHERE
klausa yang tidak akan pernah mengembalikan data.Yang bisa kita lakukan hanyalah menebak, jadi apa yang perlu Anda lakukan ketika "butuh waktu lama" adalah untuk melihat apa yang dilakukan permintaan itu yang butuh waktu lama. Jika menunggu sesuatu, maka lihat apa yang menunggu.
sumber
Bergantung pada seberapa spiky dan thread permintaan kueri Anda, sistem Anda mungkin hanya mengantri permintaan itu. Jumlah pekerja default (yaitu jumlah utas server SQL simultan) untuk pengaturan Anda harus sekitar 700.
Lihat sys.dm_os_schedulers dan sys.dm_os_waiting_tasks untuk melihat apakah itu bisa menjadi masalah.
sumber