Saya menyiapkan sistem pemantauan untuk SQL Server menggunakan Extended Events untuk menemukan pertanyaan berat sebagai 'umpan balik produksi' untuk pengembang kami. Saya menggunakan acara sp_statement_completed
dan sql_statement_completed
, dengan filter predikat pada cpu_time, membaca logis, dll. Saya berharap untuk mengagregasi hasil database_name
dan query_hash
suka ditunjukkan dalam berbagai contoh di seluruh internet, tetapi dalam hasil yang saya lihat query_hash
adalah 0 untuk semua pernyataan menggunakan EXEC, seperti pada tabel di bawah ini (timestamp dan queryhash disingkat agar mudah dibaca).
name timestamp query_hash plan_handle statement
sql_statement_completed 2016...6414 0 050056019600764... exec Shared.dbo.SyncFirm
sql_statement_completed 2016...9946 0 06003d00e01e730... exec spSetUserAuth @userid;
sql_statement_completed 2016...7184 0 0600e30028c9da0... exec spSetUserAuth @userid;
sp_statement_completed 2016...0409 9826...578 0600c00028e6aa0... SELECT obfuscated_columns FROM dbo.SomeTable
sp_statement_completed 2016...1448 8660...775 060084006d2d660... INSERT INTO dbo.SomeTable ( obfuscated_columns) EXEC(@sql)
sql_statement_completed 2016...7752 0 0600f9006c23f03... exec spSetUserAuth @userid;
sql_statement_completed 2016...1443 1304...641 06005a0008a9b11... select SUBQ.ontrackstatus, COUNT(SUBQ.ontrac
Semua hasil memiliki nilai plan_handle
dan semuanya berbeda, sehingga banyak rencana dihasilkan. Pernyataan lain tanpa query_hash
(yang pernah saya lihat) termasuk ALTER INDEX, CHECKPOINT, STATISTIK UPDATE, TRANSAKSI KOMIT, FETCH BERIKUTNYA DARI Kursor, beberapa INSERT, SELECT @variable, IF (@variable = x).
Adakah yang tahu mengapa angka query_hash
0? Saya mungkin kehilangan titik di suatu tempat tentang SQL Query Analyzer dan EXEC, tapi saya tidak dapat menemukan petunjuk untuk mengarahkan saya ke arah yang benar. Jika hasil yang saya miliki adalah 'normal', lalu bagaimana cara terbaik untuk menjumlahkan hasil? Bukankah pengelompokan menurut pernyataan termasuk literal, spasi putih, dll ... yang dihapus saat menghitung query_hash?
EDIT: seperti yang saya lihat sekarang,, EXEC SomeStoredProcedure
memulai prosedur tersimpan (jelas), dan pernyataan individu dalam prosedur tersimpan berakhir di sesi acara sebagai sp_statement_completed
acara, dan semuanya memiliki query_hash.
Jadi untuk sp_statement_completed
(yaitu pertanyaan 'nyata'), saya dapat mengumpulkan pada query_hash dan database_name, dan untuk sql_statement_completed
tanpa query_hash (EXEC SomeStoredProcedure), saya dapat menggunakan client_connection_id
untuk mengelompokkan pernyataan dalam eksekusi spesifik dari prosedur tersimpan, untuk melihat apa yang paling banyak bagian dari prosedur yang mahal.
sumber
query_hash
0 tetapi karena mengapaexec spSetUserAuth @userid;
baris memiliki pegangan rencana yang berbeda:The algorithms to match new SQL statements to existing, unused execution plans in the cache require that all object references be fully qualified.
( Sumber .) Jika semua entri itu misalnyaexec dbo.spSetUserAuth @userid;
, Anda mungkin mendapatkan pegangan rencana yang sama untuk mereka.Jawaban:
Untuk menjelaskan mengapa hash dibuat:
Ketika kami mengirimkan kueri ke server, proses algebrizer (ya itulah sebutannya) menciptakan hash, seperti tanda tangan berkode, dari kueri. Hash adalah pengidentifikasi unik. Pengidentifikasi unik untuk setiap kueri yang diberikan, termasuk semua teks yang mendefinisikan kueri, termasuk spasi dan pengembalian carriage, pengoptimal membandingkan hash ke kueri dalam cache. Jika ada kueri dalam cache yang cocok dengan kueri yang masuk ke mesin, seluruh biaya proses optimisasi dilewati dan rencana eksekusi dalam cache rencana digunakan kembali.
EXEC
memulai prosedur tersimpan yang dapat memiliki perubahan kode, karena SQL Server tahu bahwa itu tidak perlu dibandingkanEXEC
untuk mengoptimalkannya, SQL Server tidak membuat hash.sumber