如何识别 SQL Server 中的慢查询?

如何识别 SQL Server 中的慢查询?

我找到了又长又复杂的说明像这样在谷歌搜索此问题的答案时,可以找到以下简短的参考链接这个帖子

我正在寻找一个尽可能简洁的过程来生成执行时间 > some_threshold 的 SQL 查询列表。

答案1

我想答案不在这里,因为它太简单了!以下是我得出的结论:

  1. 打开SQL Server 事件探查器(在性能工具中)
  2. File -> New Trace...
  3. 连接到数据库
  4. 单击事件选择选项卡
  5. 仅选择与 SQL 查询完成相对应的事件:
    • RPC:Completed
    • SQL:BatchCompleted
  6. 点击列过滤器...
  7. 点击期间在列表中
  8. 扩张大于或等于并输入您认为“慢”的阈值时间(以毫秒为单位)
  9. 点击好的
  10. 点击跑步

如果您正在运行许多应用程序并且想要减少噪音,您可以按ApplicationName、等进行过滤。您还可以仅显示某些列,例如仅显示和。NTUserNameTextDataDuration

以下是更先进的治疗方法的探查器。

答案2

您可以使用它来获取前 10 个昂贵的查询(如果您使用的是 Sql server 2005 及更高版本):

SELECT TOP 10 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),
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 qs.total_logical_reads DESC -- logical reads
-- ORDER BY qs.total_logical_writes DESC -- logical writes
-- ORDER BY qs.total_worker_time DESC -- CPU time

答案3

使用 Profiler 跟踪(尤其是将跟踪导入数据库时​​)是一种极好的方法。

如果您使用的是 SQL Server 2005 或更高版本,DMV(动态管理视图)提供了另一种方法:

SELECT TOP 100
(total_logical_reads + total_logical_writes) / qs.execution_count AS average_IO,
(total_logical_reads + total_logical_writes) AS total_IO,
qs.execution_count AS execution_count,
SUBSTRING (qt.text,qs.statement_start_offset/2, 
     (CASE WHEN qs.statement_end_offset = -1 
        THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2 
      ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) AS indivudual_query,
o.name AS object_name,
DB_NAME(qt.dbid) AS database_name
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
LEFT OUTER JOIN sys.objects o ON qt.objectid = o.object_id
where qt.dbid = DB_ID()
ORDER BY average_IO DESC;

需要记住的一件事是,DMV 在 SQL Server 启动时被清除,因此如果您的服务器已运行 12 分钟,它可能不会告诉您很多信息。此外,它们是累积的 - 因此维护窗口(checkDB)可能会歪曲数据。

相关内容