You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SQL Server是否追踪执行查询?能否获取指定时段历史查询?

SQL Server 查询追踪与历史查询获取方案

当然可以!SQL Server确实提供了多种方式来追踪和获取已执行的查询,下面我会把可行的方法拆解开,帮你搞定过去5小时的查询追溯需求:

一、SQL Server 原生自带的功能

1. 动态管理视图(DMVs):快速查看近期缓存的查询

SQL Server有一组动态管理视图可以帮你查看已经执行过的查询统计,比如sys.dm_exec_query_statssys.dm_exec_sql_text。不过要注意,这些视图里的数据是从SQL Server启动后开始累积的,而且如果服务器内存紧张,旧的查询缓存可能会被清理掉。

如果要获取过去5小时的查询,可以用这个脚本:

SELECT 
    deqs.last_execution_time AS 执行时间,
    dest.text AS 查询语句,
    deqs.total_worker_time AS 总CPU耗时,
    deqs.execution_count AS 执行次数
FROM 
    sys.dm_exec_query_stats deqs
CROSS APPLY 
    sys.dm_exec_sql_text(deqs.sql_handle) dest
WHERE 
    deqs.last_execution_time >= DATEADD(HOUR, -5, GETDATE())
ORDER BY 
    deqs.last_execution_time DESC;

⚠️ 注意:这个方法有局限性——那些执行后没被缓存的短查询,或者已经被内存回收的查询,是查不到的。而且如果SQL Server在过去5小时内重启过,数据也会丢失。

2. 扩展事件:轻量高效的长期追踪方案

这是微软现在最推荐的追踪方式,性能开销极低,适合生产环境长期运行。不过它需要你提前创建并启动会话,如果之前没开,那也拿不到已经发生的历史数据。

创建一个捕获所有查询的扩展事件会话脚本:

CREATE EVENT SESSION [TrackAllQueries] ON SERVER 
ADD EVENT sqlserver.sql_statement_completed(
    ACTION(sqlserver.sql_text, sqlserver.username, sqlserver.client_hostname))
ADD TARGET package0.event_file(SET filename=N'C:\SQLTraces\QueryTrace.xel') -- 这里改成你自己的存储路径
WITH (STARTUP_STATE=ON); -- 设置为启动时自动开启

启动会话:

ALTER EVENT SESSION [TrackAllQueries] ON SERVER STATE=START;

之后要读取过去5小时的查询,用这个脚本:

SELECT 
    event_data.value('(event/@timestamp)[1]', 'datetime2') AS 执行时间,
    event_data.value('(event/action[@name="sql_text"]/value)[1]', 'nvarchar(max)') AS 查询语句,
    event_data.value('(event/action[@name="username"]/value)[1]', 'nvarchar(100)') AS 执行用户,
    event_data.value('(event/action[@name="client_hostname"]/value)[1]', 'nvarchar(100)') AS 客户端主机
FROM 
    (SELECT CAST(event_data AS XML) AS event_data
     FROM sys.fn_xe_file_target_read_file('C:\SQLTraces\QueryTrace*.xel', NULL, NULL, NULL)) AS x
WHERE 
    event_data.value('(event/@timestamp)[1]', 'datetime2') >= DATEADD(HOUR, -5, GETDATE())
ORDER BY 
    execution_time DESC;

这个方法能捕获几乎所有查询,包括那些没被缓存的,而且性能影响很小,非常适合长期监控。

3. SQL Server Profiler:过时的临时方案

这个工具现在已经被微软标记为过时了,因为它的性能开销很大,不适合生产环境长期使用。但如果是临时应急,你可以用它来手动捕获查询——不过同样,要是之前没开追踪,也没法拿到过去的历史数据。

二、如果之前没开追踪,这些替代方案可以试试

如果你的SQL Server之前没有任何追踪机制,那原生功能可能拿不到过去5小时的查询,这时候可以考虑这些办法:

  • 事务日志分析:如果你的数据库恢复模式是完整或大容量日志模式,可以用第三方工具(比如ApexSQL Log、Redgate SQL Log Rescue)分析事务日志,提取出数据修改类的查询(比如INSERT/UPDATE/DELETE)。但SELECT语句一般不会记录在事务日志里,所以这个方法查不到只读查询。
  • 应用层日志回溯:如果你的应用程序本身有日志系统,会记录所有发送给SQL Server的查询语句,那可以直接去应用日志里找。这是很多项目里常用的补充追踪方式。
  • 自定义日志表(未来预防):如果以后需要长期追踪,可以自己建一个日志表,然后通过数据库触发器或者应用层埋点,把所有执行的查询写入这个表。不过触发器会带来一定性能开销,需要根据业务场景权衡。

总结一下

  • 如果要追溯已经发生的过去5小时查询:只有之前已经开启了扩展事件、Profiler,或者应用层有日志,才能拿到完整数据;如果都没开,只能通过事务日志分析拿到修改类查询。
  • 如果要未来能随时追踪查询:扩展事件是最优选择,低性能开销,功能强大。

内容的提问来源于stack exchange,提问作者Gurmeet

火山引擎 最新活动