SET STATISTICS TIME ON 仅向客户端“消息”流输出执行耗时,不返回结果集,故需查看SSMS的“消息”页签;其为单次端到端测量,区别于sys.dm_exec_query_stats的纯服务端累计耗时。

SET STATISTICS TIME ON 为什么只在消息窗口出结果,不返回结果集
因为 SET STATISTICS TIME ON 是会话级开关,它不修改 SQL 逻辑,只让 SQL Server 在执行完每条语句后,额外向客户端“消息”流(不是结果集流)输出一行耗时统计。SSMS 把这两类输出分开显示:查询结果在“结果”页签,CPU/elapsed time 在“消息”页签。
常见误操作是盯着“结果”页签等数字——它根本不会出现在那里。必须切到“消息”页签,找形如 SQL Server Execution Times: CPU time = 15 ms, elapsed time = 22 ms. 的行。
- 该命令对当前连接生效,断开重连即失效
- 不能放在存储过程定义体里(
CREATE PROC内部写会报错) - 即使存储过程中有
SET NOCOUNT ON,也不影响时间统计输出
SET STATISTICS TIME ON 和 sys.dm_exec_query_stats 返回的耗时区别在哪
SET STATISTICS TIME ON 给的是单次执行的实时测量值,含网络传输、客户端渲染等端到端延迟;而 sys.dm_exec_query_stats 中的 total_elapsed_time 是 SQL Server 内部计时器采集的纯服务端耗时,精度更高、无网络干扰,但它是历史累计值(需除以 execution_count 才得平均)。
举个典型差异场景:你在 SSMS 里跑一条简单 SELECT TOP 10,SET STATISTICS TIME 显示 elapsed time = 45ms,但查 sys.dm_exec_query_stats 发现同语句平均 elapsed_time = 3ms——那多出来的 42ms 很可能就是 SSMS 渲染 10 行结果+格式化的时间。
- 临时诊断用
SET STATISTICS TIME ON,快、直观、不用权限 - 分析长期趋势或定位高频慢查询,必须查
sys.dm_exec_query_stats - 注意
sys.dm_exec_query_stats不包含当前正在运行的查询,只统计已结束的
SET STATISTICS TIME ON 开启后,为什么有时看不到 CPU time 行
最常见原因是语句执行太快,被 SQL Server 计时器截断为 0。比如本地数据库查一个带索引的小表,实际耗时 CPU time 和 elapsed time 都显示 0 ms,甚至整行不输出。
另一个隐蔽原因是并行执行:当查询启用并行度(DOP > 1)时,CPU time 是所有线程 CPU 时间总和,可能远大于 elapsed time;但如果并行任务调度开销大、实际工作少,也可能出现 CPU time = 0 而 elapsed time > 0(比如大量等待 I/O 或锁)。
- 想确认是否真没输出,先执行
SET STATISTICS TIME ON; SELECT GETDATE(); SET STATISTICS TIME OFF;看消息窗口有没有任何SQL Server Execution Times行 - 若始终不出现,检查是否在 Azure SQL 数据库中——部分托管实例默认禁用该功能,需联系管理员开启
- 不要依赖
CPU time = 0判定无性能问题,要结合sys.dm_exec_requests查wait_type
在应用代码里调用存储过程时,还能用 SET STATISTICS TIME 吗
不能直接用。因为 SET STATISTICS TIME ON 是客户端驱动行为,需要客户端明确发送该命令并解析消息流。大多数 ORM(如 Entity Framework、MyBatis)或数据库驱动(如 pyodbc、mssql-node)默认只处理结果集,忽略消息流,所以即使你把 SET STATISTICS TIME ON 拼进 SqlCommand 字符串,应用也收不到耗时数据。
如果硬要在应用侧埋点,正确做法是:在应用代码里用高精度计时器(如 C# 的 Stopwatch、Python 的 time.perf_counter())包裹整个数据库调用,测端到端延迟。这虽然含网络,但对业务层更有意义。
- SQL Server 内部真正可靠的耗时指标,只能从 DMV(如
sys.dm_exec_query_stats)或扩展事件(XEvents)里取 - 若必须在存储过程内记录自身耗时,改用
GETDATE()或SYSDATETIME()做前后差(注意精度:前者毫秒级,后者百纳秒级) - 别在生产环境长期开着
SET STATISTICS TIME ON,它会产生额外日志开销,尤其高并发时

















