Ber*_*hem 8 sql-server extended-events sql-server-2014
我正在使用扩展事件为 SQL Server 设置监控系统,以便为我们的开发人员查找大量查询作为“生产反馈”。我正在使用事件sp_statement_completed
和sql_statement_completed
,并在 cpu_time、逻辑读取等上使用谓词过滤器。我希望将结果汇总database_name
并query_hash
喜欢在互联网上的众多示例中展示的结果,但在结果中我看到query_hash
所有语句都是 0使用 EXEC,如下表所示(为了便于阅读,缩短了时间戳和查询哈希)。
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
Run Code Online (Sandbox Code Playgroud)
所有结果都有其价值,plan_handle
而且它们都不同,因此正在制定很多计划。其他没有query_hash
(我见过的)语句包括 ALTER INDEX、CHECKPOINT、UPDATE STATISTICS、COMMIT TRANSACTION、FETCH NEXT FROM Cursor、一些 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
存储过程的特定执行中的语句进行分组,以查看最多的是什么程序的昂贵部分。
解释为什么创建哈希:
当我们向服务器提交查询时,代数器(是的,这就是它的名字)进程会创建查询的哈希值,就像编码签名一样。哈希值是唯一标识符。标识符对于任何给定查询都是唯一的,包括定义查询的所有文本(包括空格和回车符),优化器将哈希与缓存中的查询进行比较。如果缓存中存在与进入引擎的查询相匹配的查询,则将跳过优化过程的整个成本,并重用计划缓存中的执行计划。
EXEC
启动一个可以更改其代码的存储过程,因为 SQL Server 知道它不需要比较EXEC
来优化它,所以 SQL Server 不会创建哈希。