为什么EXEC语句的query_hash为零?


8

我正在使用扩展事件为SQL Server设置监视系统,以查找繁重的查询作为开发人员的“生产反馈”。我正在使用event sp_statement_completedsql_statement_completed,并在cpu_time,逻辑读取等上使用谓词过滤器。我希望将结果聚合在一起,database_namequery_hash像在Internet上的众多示例中所展示的那样,但是在结果中,我看到query_hash所有语句的结果均为0使用EXEC,如下表所示(时间戳和queryhash缩短了可读性)。

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

所有结果的确具有价值,plan_handle而且各不相同,因此正在生成许多计划。没有query_hash(我见过)的其他语句包括ALTER INDEX,CHECKPOINT,UPDATE STATISTICS,COMMIT TRANSACTION,从游标获取下一个,一些INSERT,SELECT @ variable,IF(@variable = x)。

有人知道为什么query_hash是0吗?我可能错过了有关SQL查询分析器和EXEC的知识,但是我找不到任何线索来指明正确的方向。如果我得到的结果是“正常”,那么如何最好地汇总结果?按语句分组是否不包括文字,空格等...在计算query_hash时将其删除?

编辑:正如我现在看到的那样EXEC SomeStoredProcedure,启动一个存储过程(很明显),并且该存储过程中的各个语句以事件的形式结束在事件会话中sp_statement_completed,并且所有这些语句都有一个query_hash。

因此,对于sp_statement_completed(即“真实”查询),我可以在query_hash和database_name上进行汇总,而对于sql_statement_completed没有query_hash(EXEC SomeStoredProcedure)的情况,我可以使用client_connection_id来对存储过程的特定执行中的语句进行分组,以了解最有效的方法程序的昂贵部分。


2
我不知道为什么query_hash为0,但是为什么exec spSetUserAuth @userid;行具有不同的计划句柄:The algorithms to match new SQL statements to existing, unused execution plans in the cache require that all object references be fully qualified.Source。)如果所有这些条目都是例如exec dbo.spSetUserAuth @userid;,您可能会为它们获得相同的计划句柄。
Andriy M

它们具有不同的plan_handles,因为它们在不同的数据库中使用,起初我没有注意到。在这种情况下,对象引用不相同,因此计划也不同。感谢您指出。
Bert Van Landeghem '16

如果是这样的话,那不能解决您的问题吗?您可以按数据库生成有关活动的报告,并且可以通过某些过程检测参数嗅探/参数化问题。
汤姆五世

好吧,实际上是……
Bert Van Landeghem '16

3
如果您的根本问题确实已经解决,您是否可以发布答案以解释您的发现以及如何帮助解决问题?您不必这样做,但是,如果这可以以任何方式激发您的灵感,那么这可能是对该站点的知识库的宝贵贡献。请记住,我们希望保留注释,只要它们有助于澄清问题/答案,因此,请随时重复这些注释中已提及的所有观点,以便以后可以安全地删除它们。
Andriy M

Answers:


1

要解释为什么创建哈希:

当我们向服务器提交查询时,代数程序(是的就是所谓的)过程创建查询的哈希,例如编码签名。哈希是唯一标识符。标识符对于任何给定查询都是唯一的,包括定义查询的所有文本(包括空格和回车符),优化器会将哈希与缓存中的查询进行比较。如果高速缓存中存在与进入引擎的查询匹配的查询,那么将跳过优化过程的全部成本,并重用计划高速缓存中的执行计划。

EXEC启动一个可以更改其代码的存储过程,因为SQL Server知道不需要对其进行比较EXEC以对其进行优化,因此SQL Server不会创建哈希。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.