在MSSQL中查询执行记录最简单的方法是使用系统视图sys.dm_exec_sessions和sys.dm_exec_requests。执行以下查询即可查看当前所有会话的执行详情:
SELECT s.session_id, s.login_name, s.host_name, s.program_name, r.status, r.command, r.start_time, r.percent_complete, t.text AS current_query FROM sys.dm_exec_sessions s LEFT JOIN sys.dm_exec_requests r ON s.session_id = r.session_id CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t WHERE s.is_user_process = 1 ORDER BY s.session_id;
实时监控SQL执行
使用这个查询,你可以实时看到每个会话的当前SQL语句、执行状态、开始时间和完成百分比。高效运维的关键就是快速定位慢查询或阻塞会话,让数据管理更自信。
历史执行记录查询
要查看历史执行记录,可以启用查询商店(Query Store)。先开启:ALTER DATABASE [你的数据库] SET QUERY_STORE = ON; 然后查询:SELECT qt.query_sql_text, rs.avg_duration, rs.count_executions, rs.last_execution_time FROM sys.query_store_query_text qt JOIN sys.query_store_query q ON qt.query_text_id = q.query_text_id JOIN sys.query_store_plan p ON q.query_id = p.query_id JOIN sys.query_store_runtime_stats rs ON p.plan_id = rs.plan_id ORDER BY rs.avg_duration DESC;
使用DMV查看详细执行计划
对于特定查询的执行计划,使用:SELECT * FROM sys.dm_exec_query_stats CROSS APPLY sys.dm_exec_sql_text(sql_handle) WHERE sql_handle = 0x...; 这能帮你分析CPU时间、逻辑读取等指标,优化性能。
追踪长时间运行查询
设置一个简单的脚本来每分钟检查长时间查询:DECLARE @timeout INT = 300; -- 5分钟 SELECT session_id, start_time, DATEDIFF(SECOND, start_time, GETDATE()) AS running_seconds FROM sys.dm_exec_requests WHERE status = 'running' AND DATEDIFF(SECOND, start_time, GETDATE()) > @timeout;
使用Extended Events捕获执行记录
创建Extended Events会话来记录所有SQL执行:CREATE EVENT SESSION [TrackSQLExec] ON SERVER ADD EVENT sqlserver.sql_statement_completed (ACTION(sqlserver.sql_text, sqlserver.session_id)) ADD TARGET package0.event_file(SET filename=N'C:\temp\TrackSQLExec.xel'); ALTER EVENT SESSION [TrackSQLExec] ON SERVER STATE = START;
查询阻塞会话
快速查询阻塞:SELECT blocking_session_id, session_id, wait_type, wait_time FROM sys.dm_exec_requests WHERE blocking_session_id <> 0; 这在运维中超级实用,能立即发现问题。
FAQ
Q: 如何快速停止一个慢查询?
A: 用KILL 52; 替换52为session_id。
Q: 查询商店会占用多少空间?
A: 可以设置上限:ALTER DATABASE [db] SET QUERY_STORE (MAX_STORAGE_SIZE_MB = 1000);
Q: 如何查看最近的错误执行?
A: SELECT * FROM sys.dm_exec_sessions WHERE last_request_end_time > DATEADD(mi, -10, GETDATE());
Q: DMV数据会丢失吗?
A: 是的,重启SQL Server后DMV清空,使用Query Store持久化。