You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Microsoft SQL Server 2016(SP1)中简洁捕获并记录所有数据库查询?

嘿,针对你在SQL Server 2016(SP1)上要捕获并记录所有运行查询的需求,我整理了两种实用方案——适合临时场景的简洁实现,以及生产环境的最优解决方案,你可以根据自己的使用场景来选:

一、简洁快速实现(测试/临时排查首选)

如果只是短时间内需要捕获查询,或者在测试环境做验证,SQL Server Profiler是最容易上手的方式,图形化操作零门槛:

  • 打开SSMS,连接到目标实例,右键服务器 → 「跟踪」→ 「新建跟踪」
  • 在「常规」选项卡选择「空白」模板,切换到「事件选择」页,勾选以下两个核心事件:
    • SQL:BatchCompleted:捕获所有批量执行的SQL语句(比如直接在SSMS里跑的查询)
    • RPC:Completed:捕获存储过程或远程过程调用
  • 可以按需添加额外列,比如Duration(执行时长)、CPU(CPU占用)、LoginName(执行用户)、DatabaseName(目标库),然后启动跟踪就能实时看到所有执行的查询,还能选择保存到文件或数据库表。

⚠️ 注意:Profiler对服务器性能影响较大(通常会带来10%-30%的开销),绝对不要在高负载生产环境长期运行!

二、生产环境最优解决方案(性能友好,长期运行)

微软官方推荐的轻量级跟踪方案是Extended Events(扩展事件),它的性能开销仅为Profiler的1/5甚至更低(通常在5%以内),完全适合生产环境长期运行:

方式1:SSMS图形化创建(直观易操作)

  1. 展开服务器 → 「管理」→ 「扩展事件」→ 「会话」→ 「新建会话」
  2. 选择「空白会话」,给会话起个名字(比如CaptureAllQueries)
  3. 在「事件」页,添加两个核心事件:
    • sql_statement_completed:捕获单条SQL语句执行完成的事件
    • rpc_completed:捕获存储过程调用完成的事件
  4. 切换到「数据列」页,添加你需要追踪的字段,比如database_name、username、duration、cpu_time、sql_text
  5. 在「存储」页,选择将事件保存到事件文件(性能最优),设置文件大小上限和滚动更新的文件数量,避免磁盘被占满
  6. 启动会话后,右键会话 → 「查看目标数据」就能实时查看捕获的查询;也可以用T-SQL查询事件文件:
SELECT 
    event_data.value('(event/@name)[1]', 'varchar(50)') AS EventName,
    event_data.value('(event/@timestamp)[1]', 'datetime2') AS EventTime,
    event_data.value('(event/data[@name="database_name"]/value)[1]', 'varchar(100)') AS DatabaseName,
    event_data.value('(event/data[@name="username"]/value)[1]', 'varchar(100)') AS Username,
    event_data.value('(event/data[@name="sql_text"]/value)[1]', 'nvarchar(max)') AS SQLText
FROM 
    (SELECT CAST(event_data AS XML) AS event_data 
     FROM sys.fn_xe_file_target_read_file('C:\XEvents\CaptureAllQueries*.xel', NULL, NULL, NULL)) AS x
ORDER BY EventTime DESC;

方式2:T-SQL快速创建(适合自动化/脚本化)

如果需要批量部署或快速创建,直接执行以下脚本即可:

-- 创建扩展事件会话
CREATE EVENT SESSION CaptureAllQueries ON SERVER 
ADD EVENT sqlserver.rpc_completed(
    ACTION(sqlserver.database_name, sqlserver.username, sqlserver.sql_text)),
ADD EVENT sqlserver.sql_statement_completed(
    ACTION(sqlserver.database_name, sqlserver.username, sqlserver.sql_text))
ADD TARGET package0.event_file(SET filename=N'C:\XEvents\CaptureAllQueries.xel', max_file_size=(100), max_rollover_files=(5))
WITH (MAX_MEMORY=4096 KB, EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS, MAX_DISPATCH_LATENCY=30 SECONDS, MAX_EVENT_SIZE=0 KB, MEMORY_PARTITION_MODE=NONE, TRACK_CAUSALITY=OFF, STARTUP_STATE=ON);
GO

-- 启动会话
ALTER EVENT SESSION CaptureAllQueries ON SERVER STATE = START;

这个脚本会创建一个自动启动的会话,将查询记录保存到C:\XEvents目录下,最多保留5个100MB的文件,避免磁盘溢出。

额外补充:非实时查询捕获

如果只是需要查看已经执行过的查询(不需要实时跟踪),可以查询动态管理视图,虽然无法覆盖所有查询(比如执行后被逐出缓存的),但足够满足大部分排查需求:

SELECT 
    DB_NAME(q.dbid) AS DatabaseName,
    s.login_name,
    q.text AS SQLText,
    q.last_execution_time
FROM sys.dm_exec_query_stats s
CROSS APPLY sys.dm_exec_sql_text(s.sql_handle) q
ORDER BY q.last_execution_time DESC;

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:32:40