DMV是SQL Server最轻量实时的性能监控入口,需正确选用视图、添加过滤条件并规避缓存延迟;核心视图为sys.dm_exec_query_stats(查高成本SQL)、sys.dm_os_wait_stats(查等待瓶颈)、sys.dm_exec_requests+sys.dm_exec_sessions(查实时阻塞链)。

直接结论:DMV 是 SQL Server 中最轻量、最实时的性能监控入口,不需要额外安装或开启代理,但必须用对视图、加对过滤、避开缓存延迟。
哪些 DMV 最值得优先查
不是所有 DMV 都适合日常性能盯梢。以下三个是高频、低开销、信息密度高的核心视图:
-
sys.dm_exec_query_stats:查“谁在吃资源”,按逻辑读、CPU 时间、执行次数排序,能快速揪出高成本 SQL。注意它只统计已缓存的执行计划,刚编译的新查询可能还没进统计。 -
sys.dm_os_wait_stats:查“卡在哪”,比如cxpacket高说明并行过度,pageiolatch_sh持续 >20% 说明磁盘 I/O 跟不上,LCK_M_XX多则提示锁争用严重。 -
sys.dm_exec_requests+sys.dm_exec_sessions:查“正在发生什么”,能立刻看到阻塞链(blocking_session_id)、语句状态(status)、等待类型(wait_type)和已运行时间(total_elapsed_time)。
查的时候容易漏掉的关键过滤条件
不加过滤的 DMV 查询等于看噪音。常见疏漏点:
- 在
sys.dm_exec_query_stats中漏掉qs.last_execution_time > DATEADD(minute, -5, GETDATE())—— 否则会混入历史冷查询,掩盖当前问题。 - 查
sys.dm_os_wait_stats时没排除系统等待项,比如WAITFOR、SLEEP、XE_TIMER_EVENT,这些是正常后台行为,不算瓶颈。 - 用
sys.dm_exec_requests查阻塞时,忘了 JOINsys.dm_exec_sql_text获取实际 SQL 文本,只看sql_handle根本没法定位问题语句。
为什么刚执行完的慢查询可能不在 sys.dm_exec_query_stats 里
这个视图的数据来自执行计划缓存,但有几种情况会导致“查不到”:
- 查询被强制重编译(加了
OPTION(RECOMPILE)),每次执行都生成新计划,不累积统计。 - 服务器内存压力大,计划被提前从缓存中驱逐(
plan_handle对应的缓存条目已不存在)。 - 查询本身未完成(如卡在等待中),就不会计入
execution_count,也不会更新耗时类字段。
这时得切到 sys.dm_exec_requests 实时抓活的会话,再用 sys.dm_exec_sql_text(request.sql_handle) 提取语句。
别把 DMV 当“全量日志”来依赖
DMV 是内存快照,不是持久化日志。重启服务后所有计数器归零,sys.dm_os_wait_stats 的累计值就丢了;sys.dm_exec_query_stats 的统计也全部清空。如果要长期趋势分析,必须配合定时采集脚本,把关键指标(如每 5 分钟的 top 5 逻辑读 SQL)写入自建监控表。否则你只能回答“现在怎么了”,答不了“过去一小时怎么变的”。



















