Mengapa query_hash nol untuk pernyataan EXEC?

8

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_completeddan sql_statement_completed, dengan filter predikat pada cpu_time, membaca logis, dll. Saya berharap untuk mengagregasi hasil database_namedan query_hashsuka ditunjukkan dalam berbagai contoh di seluruh internet, tetapi dalam hasil yang saya lihat query_hashadalah 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_handledan 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_hash0? 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 SomeStoredProcedurememulai prosedur tersimpan (jelas), dan pernyataan individu dalam prosedur tersimpan berakhir di sesi acara sebagai sp_statement_completedacara, 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_completedtanpa query_hash (EXEC SomeStoredProcedure), saya dapat menggunakan client_connection_iduntuk mengelompokkan pernyataan dalam eksekusi spesifik dari prosedur tersimpan, untuk melihat apa yang paling banyak bagian dari prosedur yang mahal.

Bert Van Landeghem
sumber
2
Saya tidak tahu mengapa query_hash0 tetapi karena mengapa exec 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 misalnya exec dbo.spSetUserAuth @userid;, Anda mungkin mendapatkan pegangan rencana yang sama untuk mereka.
Andriy M
Mereka memiliki plan_handles berbeda karena mereka digunakan dalam database yang berbeda, saya tidak memperhatikan itu pada awalnya. Dalam hal ini, referensi objek tidak sama, maka rencana yang berbeda. Terima kasih telah menunjukkan.
Bert Van Landeghem
Jika itu masalahnya bukankah itu akan menyelesaikan masalah Anda? Anda dapat membuat laporan tentang aktivitas dengan basis data, dan Anda akan dapat mendeteksi masalah sniffing parameter / parametrization dengan prosedur tertentu.
Tom V - coba topanswers.xyz
Ya, ya sebenarnya ...
Bert Van Landeghem
3
Jika masalah mendasar Anda memang telah diselesaikan, dapatkah Anda memposting jawaban yang menjelaskan temuan Anda dan bagaimana hal itu membantu menyelesaikan masalah? Anda tidak harus tetapi, jika ini dapat menginspirasi Anda dengan cara apa pun, itu bisa menjadi kontribusi yang berharga bagi basis pengetahuan situs ini. Ingatlah bahwa kami lebih suka menyimpan komentar selama mereka membantu memperjelas pertanyaan / jawaban, jadi jangan ragu untuk mengulangi poin yang sudah disebutkan dalam komentar ini sehingga nanti dapat dihapus dengan aman.
Andriy M

Jawaban:

1

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.

EXECmemulai prosedur tersimpan yang dapat memiliki perubahan kode, karena SQL Server tahu bahwa itu tidak perlu dibandingkan EXECuntuk mengoptimalkannya, SQL Server tidak membuat hash.

James Rhoat
sumber