查SQL Server当前负载应直接用sys.dm_exec_sessions和sys.dm_exec_requests,而非sp_who2或已废弃的sysprocesses;需JOIN sys.dm_exec_sql_text获取SQL文本,WHERE条件用total_elapsed_time>30000且session_id>50,并结合wait_type与query_plan分析根因。

查 SQL Server 当前运行负载用什么函数
直接看 sys.dm_exec_sessions 和 sys.dm_exec_requests,这两个动态管理视图(DMV)是实时诊断的核心入口。别去翻 sp_who2——它只是对前两者的封装,字段少、过滤弱、还带额外开销。
常见错误是只查 sysprocesses(已废弃),或依赖 Windows 性能计数器——它们延迟高、聚合粒度粗,定位不到具体慢查询。
-
sys.dm_exec_sessions看谁连上了、用了什么登录名、是否阻塞、CPU/内存累计消耗 -
sys.dm_exec_requests看当前正在跑的语句、状态(running/suspended)、等待类型(PAGEIOLATCH_SH、LCK_M_X)、执行时间、阻塞链 - 必须 JOIN
sys.dm_exec_sql_text(<code>sql_handle) 才能看到实际 SQL 文本,否则只有sql_handle这个哈希值
识别长时间运行查询的正确 WHERE 条件
不能只写 WHERE status = 'running',很多“卡住”的请求其实是 suspended(等 I/O 或锁),真正耗时的是 total_elapsed_time > 30000(单位毫秒)这类硬指标。
容易踩的坑:用 start_time 做比较会漏掉重用执行计划的请求(start_time 是本次执行开始时间,不是语句首次编译时间);而 total_elapsed_time 是累计值,更反映真实负担。
- 查超过 30 秒的活跃请求:
WHERE total_elapsed_time > 30000 AND status IN ('running', 'suspended') - 排除系统会话:
AND session_id > 50(SQL Server 系统会话 ID ≤ 50) - 想看阻塞源头,加
AND blocking_session_id = 0,再反查被它阻塞的blocking_session_id = [id]
获取执行计划和等待详情必须配对调用
只看 sys.dm_exec_requests.wait_type 不够,比如 ASYNC_NETWORK_IO 表示客户端取数慢,不是数据库问题;WRITELOG 才真可能指向日志写入瓶颈。得结合 sys.dm_exec_query_plan(<code>plan_handle) 看执行计划里有没有全表扫描、缺少索引提示、并行度异常。
性能影响要注意:sys.dm_exec_query_plan() 是高开销操作,别在大并发下 SELECT 所有行;生产环境建议加 TOP 10 + WHERE 限定高耗时请求。
- 等待时间长但 CPU 低 → 通常是 I/O 或锁问题,重点看
wait_type和wait_duration_ms - CPU 高且
status = 'running'→ 看query_plan是否有大量排序、哈希连接、隐式转换 -
plan_handle为空说明计划已从缓存清除,此时sql_handle仍可取文本,但无法还原执行计划
MySQL / PostgreSQL 用户别套用 SQL Server 的函数名
SQL Server 的 sys.dm_exec_* 在 MySQL 里对应的是 performance_schema 表(如 events_statements_current、session_connect_attrs),PostgreSQL 则是 pg_stat_activity 和 pg_blocking_pids() 函数。名字不通用,语法也不兼容。
最常被忽略的一点:MySQL 5.7 默认关闭 performance_schema,查出来永远空;PostgreSQL 需要 track_activities = on 才能记录会话状态。权限也常不到位——SELECT 权限不够,得 PROCESS(MySQL)或 pg_read_all_stats(PG)角色。
- MySQL 启用后查慢查询:
SELECT * FROM performance_schema.events_statements_current WHERE TIMER_WAIT > 30000000000(单位皮秒) - PostgreSQL 查阻塞:
SELECT * FROM pg_stat_activity WHERE pid IN (SELECT blocked_pid FROM pg_blocking_pids(pid)) - 跨数据库写监控脚本时,先判断
@@version或current_setting('server_version'),再分支处理
事情说清了就结束。不同版本对 DMV 字段支持有差异,比如 SQL Server 2016+ 才有 query_hash 和 query_plan_hash,老版本得靠文本哈希做归类。


















