Получение ежедневного общего количества выполнений для каждой хранимой процедуры с помощью таблиц хранилища запросов?

#sql-server #sql-query-store

Вопрос:

Я пытаюсь получить ежедневное количество выполнений определенной хранимой процедуры с помощью таблиц хранилища запросов. Моя первоначальная мысль заключалась в том, что это должно сработать:

 SELECT   RunDate = convert(varchar(10), first_execution_time,121)   ' '   left(DATENAME(WEEKDAY, first_execution_time), 1)  ,TotalExecutions = sum(rs.count_executions)  ,TotalCPU = sum(round(rs.avg_cpu_time , 0) * rs.count_executions)  ,TotalLogicalReads = sum(round(rs.avg_cpu_time , 0) * round(rs.avg_logical_io_reads ,0))  ,TotalQueries = count(distinct q.query_id)  -- Comment out unless necessary...takes a long time  -- ,ExecutionPlan = CAST(p.query_plan as XML) FROM sys.query_store_runtime_stats rs JOIN sys.query_store_plan p ON p.plan_id = rs.plan_id JOIN sys.query_store_query q ON q.query_id = p.query_id WHERE   Object_Name(q.object_id) = 'API_SPName' Group by convert(varchar(10), first_execution_time,121)   ' '   left(DATENAME(WEEKDAY, first_execution_time), 1)  Order by RunDate desc  

Затем я понял, что я переоцениваю общее количество выполнений, если в хранимой процедуре имеется несколько отдельных операторов SQL.

Я подумал тогда, что (предполагая, что в sp есть 1 оператор, который ВСЕГДА будет выполняться, без «если» вокруг него), если я просто возьму идентификатор запроса, у которого больше всего выполнений, и отфильтрую его, это даст общее количество выполнений в день.

Однако это не работает. Когда я выполняю следующее (аналогично приведенному выше, но без группировки по дням), после самого последнего дня идентификатор запроса все тот же! Это процедура, в которой содержится множество утверждений. Таким образом, у него должно быть много различных идентификаторов запросов.

 SELECT   RunDate = convert(varchar(16), first_execution_time,121)  ,TotalExecutions = rs.count_executions  ,q.query_id  ,p.plan_id  ,AverageCPU = round(rs.avg_cpu_time , 0)  ,AverageLogicalReads = round(rs.avg_logical_io_reads ,0)  -- Comment out unless necessary...takes a long time  -- ,ExecutionPlan = CAST(p.query_plan as XML) FROM sys.query_store_runtime_stats rs JOIN sys.query_store_plan p ON p.plan_id = rs.plan_id JOIN sys.query_store_query q ON q.query_id = p.query_id WHERE   Object_Name(q.object_id) = 'API_SPName'  -- and q.query_id = 3198102 Order by RunDate desc    

Есть какие-нибудь мысли о том, что здесь может происходить? Есть ли какой-либо другой способ выяснить, сколько раз хранимая процедура выполнялась ежедневно? Также в качестве примечания — хранимые процедуры, содержащие всего 1 оператор, кажутся точными, когда я вычисляю общее количество выполнений в день

Комментарии:

1. Рассмотрите возможность создания периодических снимков sys.dm_exec_procedure_stats в таблицу. Счетчики накапливаются и сбрасываются при перезапуске экземпляра, но вы все равно можете подсчитать количество ежедневных счетчиков. Я делаю это каждую минуту и нахожу информацию бесценной.

2. Побочные моменты: Чтобы сократить дату, ее более эффективно использовать cast(... as date) . В вашем GROUP BY случае также более эффективно группировать по фактическим значениям, а не по строковой форме (вы можете их впоследствии упорядочить), поэтому вам следует GROUP BY CAST(first_execution_time AS date) затем определить день недели в SELECT