在SQL Server中捕获前100个昂贵的查询(< 2014)

时间:2016-10-12 19:42:32

标签: sql-server sql-server-2008 tsql sql-server-2012

我试图每天捕获昂贵的查询并将其保存到表中以供进一步分析。我每天都在工作,每天晚上都会这样做。

使用以下代码捕获代价高昂的查询:

CREATE TABLE [dbo].[CostlyQueries](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [QueryText] [nvarchar](max) NULL,
    [execution_count] [bigint] NOT NULL,
    [total_logical_reads] [bigint] NOT NULL,
    [last_logical_reads] [bigint] NOT NULL,
    [total_logical_writes] [bigint] NOT NULL,
    [last_logical_writes] [bigint] NOT NULL,
    [total_worker_time] [bigint] NOT NULL,
    [last_worker_time] [bigint] NOT NULL,
    [total_elapsed_time_in_S] [bigint] NULL,
    [last_elapsed_time_in_S] [bigint] NULL,
    [last_execution_time] [datetime] NULL,
    [query_plan] [xml] NULL,
    [DateAdded] [datetime] NULL DEFAULT (getdate())
)


INSERT INTO CostlyQueries (QueryText, execution_count, total_logical_reads, last_logical_reads, total_logical_writes, [last_logical_writes], total_worker_time, last_worker_time
    , total_elapsed_time_in_S, last_elapsed_time_in_S, last_execution_time, query_plan )
SELECT TOP 100 SUBSTRING(qt.TEXT, (qs.statement_start_offset/2)+1,
    ((CASE qs.statement_end_offset
    WHEN -1 THEN DATALENGTH(qt.TEXT)
    ELSE qs.statement_end_offset
    END - qs.statement_start_offset)/2)+1) AS QueryText,
    qs.execution_count,
    qs.total_logical_reads, qs.last_logical_reads,
    qs.total_logical_writes, qs.last_logical_writes,
    qs.total_worker_time,
    qs.last_worker_time,
    qs.total_elapsed_time/1000000 total_elapsed_time_in_S,
    qs.last_elapsed_time/1000000 last_elapsed_time_in_S,
    qs.last_execution_time,
    qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY last_elapsed_time_in_S desc,
qs.total_worker_time DESC -- CPU time

这里有两个问题:

  
      
  1. 当这些DMV(系统数据)刷新时?我读过的地方会在回收sql服务时刷新。有人有详细信息吗?

  2.   
  3. 我编写的用于捕获代价高昂的查询的查询使用sys.dm_exec_query_stats,由于某种原因它在周末没有捕获长时间运行的查询。任何人都可以帮助纠正/获取更多详细信息,以便我们可以捕获更多指标吗?

  4.   

根据Aaron Bertrand在以下评论中建议添加了正确的查询: - 更改交叉申请到外部申请 -

SELECT TOP 100 SUBSTRING(qt.TEXT, (qs.statement_start_offset/2)+1,
    ((CASE qs.statement_end_offset
    WHEN -1 THEN DATALENGTH(qt.TEXT)
    ELSE qs.statement_end_offset
    END - qs.statement_start_offset)/2)+1) AS QueryText,
    qs.execution_count,
    qs.total_logical_reads, qs.last_logical_reads,
    qs.total_logical_writes, qs.last_logical_writes,
    qs.total_worker_time,
    qs.last_worker_time,
    qs.total_elapsed_time/1000000 total_elapsed_time_in_S,
    qs.last_elapsed_time/1000000 last_elapsed_time_in_S,
    qs.last_execution_time,
    qp.query_plan
FROM sys.dm_exec_query_stats qs
OUTER APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
OUTER APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY last_elapsed_time_in_S desc,
qs.total_worker_time DESC -- CPU time

2 个答案:

答案 0 :(得分:2)

只要计划在缓存中,数据就会保留在DMV中。由于几个不同的原因(内存压力,重新编译等),计划可以从缓存中删除。此外,诸如更改设置或重新启动服务器等各种事情当然会清除所有内容。

如果你想让它在某种程度上可靠,你必须经常运行它,这样任何重要的东西都不会丢失。

答案 1 :(得分:1)

进行自己的分析没有任何问题,因为它总是100%根据您的需求量身定制,但是,我建议您同时查看SQL Server数据收集器和Data Collection Sets