一、查询最近执行的SQL语句
查询最近执行的SQL语句可以通过系统视图sys.dm_exec_query_stats来实现,该视图存储了SQL Server最近执行的查询信息,包括SQL语句、执行次数、消耗的CPU时间和I/O等。以下是一个查询最近执行的SQL语句的代码示例:
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) AS query, qs.execution_count, qs.total_worker_time/1000000 AS total_cpu_time_sec, qs.total_elapsed_time/1000000 AS total_elapsed_time_sec, qs.total_logical_reads, qs.total_physical_reads, qs.creation_time, ISNULL(DB_NAME(qt.dbid), 'Resource') AS dbname, qt.objectid, qt.dbid FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt ORDER BY qs.total_worker_time DESC;
执行以上代码可以获取到最近执行的10条SQL语句,包含SQL语句文本、执行次数、CPU时间、耗时、逻辑读取次数、物理读取次数、创建时间、数据库名称、对象ID和数据库ID等信息。
二、查询最耗费CPU时间的SQL语句
查询最耗费CPU时间的SQL语句可以通过sys.dm_exec_query_stats视图中的total_worker_time来实现。以下是一个查询最耗费CPU时间的SQL语句的代码示例:
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) AS query, qs.execution_count, qs.total_worker_time/1000000 AS total_cpu_time_sec, ISNULL(DB_NAME(qt.dbid), 'Resource') AS dbname FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt ORDER BY qs.total_worker_time DESC;
执行以上代码可以获取最耗费CPU时间的10条SQL语句。以上代码中的total_worker_time/1000000是因为sys.dm_exec_query_stats视图中的total_worker_time是以微秒为单位的。查询结果包含SQL语句、执行次数、CPU时间和数据库名称。
三、查询最慢的SQL语句
查询最慢的SQL语句可以通过sys.dm_exec_query_stats视图中的total_elapsed_time来实现。以下是一个查询最慢的SQL语句的代码示例:
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) AS query, qs.execution_count, qs.total_elapsed_time/1000000 AS total_elapsed_time_sec, ISNULL(DB_NAME(qt.dbid), 'Resource') AS dbname FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt ORDER BY qs.total_elapsed_time DESC;
执行以上代码可以获取最慢的10条SQL语句。以上代码中的total_elapsed_time/1000000是因为sys.dm_exec_query_stats视图中的total_elapsed_time是以微秒为单位的。查询结果包含SQL语句、执行次数、耗时和数据库名称。
四、查询最频繁被执行的SQL语句
查询最频繁被执行的SQL语句可以通过sys.dm_exec_query_stats视图中的execution_count来实现。以下是一个查询最频繁被执行的SQL语句的代码示例:
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) AS query, qs.execution_count, qs.total_worker_time/qs.execution_count/1000000 AS avg_cpu_time_sec_per_exec, qs.total_elapsed_time/qs.execution_count/1000000 AS avg_elapsed_time_sec_per_exec, qs.total_logical_reads/qs.execution_count AS avg_logical_reads_per_exec, qs.total_physical_reads/qs.execution_count AS avg_physical_reads_per_exec, ISNULL(DB_NAME(qt.dbid), 'Resource') AS dbname FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt ORDER BY qs.execution_count DESC;
执行以上代码可以获取最频繁被执行的10条SQL语句。以上代码中的total_worker_time/qs.execution_count/1000000和total_elapsed_time/qs.execution_count/1000000是因为需要计算每次执行的平均CPU时间和平均耗时。查询结果包含SQL语句、执行次数、平均CPU时间、平均耗时、平均逻辑读取次数、平均物理读取次数和数据库名称等信息。
五、查询最占用内存的SQL语句
查询最占用内存的SQL语句可以通过sys.dm_exec_query_stats视图中的total_logical_reads和total_physical_reads来实现。以下是一个查询最占用内存的SQL语句的代码示例:
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) AS query, qs.execution_count, qs.total_logical_reads, qs.total_physical_reads, ISNULL(DB_NAME(qt.dbid), 'Resource') AS dbname FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt ORDER BY (qs.total_logical_reads + qs.total_physical_reads) DESC;
执行以上代码可以获取最占用内存的10条SQL语句。查询结果包含SQL语句、执行次数、逻辑读取次数、物理读取次数和数据库名称。
六、结语
通过以上方法可以查询出SQL Server最近执行的SQL语句,并通过不同的维度进行排列和分析,有助于发现性能瓶颈和优化SQL Server的性能。