Я настраиваю систему мониторинга для 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
Все результаты имеют значение, 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
для группировки операторов в рамках конкретного выполнения хранимой процедуры, чтобы увидеть, что наиболее дорогостоящая часть процедуры.
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.
( Источник .) Если бы все эти записи были, напримерexec dbo.spSetUserAuth @userid;
, вы могли бы получить идентичные дескрипторы плана для них.