查找慢的Sql语句
本文将带你用最简单的方式监控sql的运行时间。在一个非常繁忙的系统上,一次运行成百上千的 sql,因此找到并微调运行速度较慢的 sql 很重??要。
以下 sql 片段打印前 5 个较慢的 sql 语句。
SELECT TOP 5 qs.total_elapsed_time / qs.execution_count / 1000000.0 AS average_seconds, qs.total_elapsed_time / 1000000.0 AS total_seconds, qs.execution_count, qs.total_rows, qs.last_rows, qs.min_rows, qs.max_rows, SUBSTRING(qt.text,qs.statement_start_offset/2 +1, (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+1 ) AS individual_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_seconds DESC;
SELECT qs.execution_count , SUBSTRING(qt.text, qs.statement_start_offset / 2 + 1, ( 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 query_text , o.name AS objectname , dbname = DB_NAME(qt.dbid) , qs.total_rows , qs.last_rows , qs.min_rows , qs.max_rows FROM sys.dm_exec_query_stats AS 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('数据库名') AND qt.text LIKE '%SELECT%' ORDER BY qs.execution_count DESC;
SELECT TOP 20 total_worker_time / 1000 AS [总消耗CPU 时间(ms)] , execution_count [运行次数] , qs.total_worker_time / qs.execution_count / 1000 AS [平均消耗CPU 时间(ms)] , last_execution_time AS [最后一次执行时间] , max_worker_time / 1000 AS [最大执行时间(ms)] , SUBSTRING(qt.text, qs.statement_start_offset / 2 + 1, ( CASE WHEN qs.statement_end_offset = -1 THEN DATALENGTH(qt.text) ELSE qs.statement_end_offset END - qs.statement_start_offset ) / 2 + 1) AS [使用CPU的语法] , qt.text [完整语法] , dbname = DB_NAME(qt.dbid) , OBJECT_NAME(qt.objectid, qt.dbid) ObjectName FROM sys.dm_exec_query_stats qs WITH ( NOLOCK ) CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt WHERE execution_count > 1 ORDER BY total_worker_time DESC;
上面的代码片段使用sys.dm_exec_query_stats视图,它只返回缓存的查询计划。因此,当从缓存中删除计划时,相应的行将从该视图中删除。
上面的代码片段将输出十个字段,individual_query
, object_name
,分别database_name
代表正在运行的 sql 文本、对象名称和数据库名称。average_seconds
, total_seconds
,execution_count
帮助您跟踪 CPU 成本时间。total_rows
, last_rows
, min_rows
,max_rows
帮助您跟踪查询返回的行数。
qt.dbid = DB_ID('Your DB Name')
指定要监视的数据库。如果要对所有数据库进行捕获,则可以删除此预测条件。
概括
sys.dm_exec_query_stats
显示当前可用的缓存计划,而不是所有计划。sys.dm_exec_query_stats
很容易跟踪sql的运行时间、执行次数、返回行等……- 您可以使用
sys.dm_exec_query_stats
来完成更全面的功能,例如:自动将慢速 sql 语句写入日志文件。