第十期:性能监控与调优方法论 —— 从等待统计到DMV分析
Clyde Jin
04-25
DBA
166

第十期:性能监控与调优方法论 —— 从等待统计到DMV分析

1. 性能优化的核心思维:基于证据,而非直觉

三个关键转变

| 从 | 到 |

|—-|—-|

| “我觉得这里慢” | “等待统计显示这里花了X%时间” |

| “重启一下试试” | “定位具体瓶颈类型(CPU/IO/网络/锁)” |

| “加个索引吧” | “分析执行计划+等待类型后再决定” |

核心方法论Waits and Queues(等待与队列)

  • SQL Server 的性能问题最终都会表现为等待(某个资源不可用)

  • 找出TOP等待类型 → 定位瓶颈资源 → 针对性优化

2. 等待类型分类与解读

等待类型三大类(按可优化性排序):

| 类别 | 定义 | 典型等待 | 处理方向 |

|——|——|———-|———-|

| 资源等待 | 等待CPU、内存、I/O等硬件资源 | WRITELOG, PAGEIOLATCH_*, SOS_SCHEDULER_YIELD | 升级硬件或优化使用方式 |

| 锁等待 | 等待锁释放 | LCK<em>M</em>* | 优化查询、索引、隔离级别 |

| 外部等待 | 等待外部应用或网络 | OLEDB, BROKER<em>*, PREEMPTIVE</em>* | 检查外部依赖 |

TOP 10 常见等待类型速查

| 等待类型 | 含义 | 最常见原因 | 针对性排查 |

|———-|——|————|————|

| PAGEIOLATCH_SH | 等待从磁盘读页到内存 | 内存不足,或缺失索引导致大量物理读 | 检查缓冲池命中率,检查缺失索引 |

| WRITELOG | 等待日志写入磁盘 | 事务提交频繁,日志磁盘慢 | 批量提交,日志盘换SSD,检查磁盘队列 |

| LCK_M_X | 等待排他锁 | 长事务、锁升级、并发写冲突 | 查sys.dm_tran_locks,优化长事务 |

| SOS_SCHEDULER_YIELD | 自愿让出CPU(等待调度)| CPU压力大,查询未优化 | 检查CPU使用率,优化高代价查询 |

| ASYNC_NETWORK_IO | 等待客户端接收数据 | 客户端处理慢,网络慢 | 检查客户端应用,网络带宽 |

| PAGELATCH_EX | 等待页闩锁(内存结构)| tempdb竞争(PFS/GAM/SGAM页)| tempdb增加文件,使用分区表 |

| CXPACKET | 等待并行查询同步 | 并行查询的不均衡分布 | 调整MAXDOP,优化倾斜数据分布 |

| BACKUPTHREAD | 等待备份完成 | 备份任务占用资源 | 维护窗口做备份,调整备份压缩 |

| LOGBUFFER | 等待日志缓冲区空间 | 日志生成过快,磁盘跟不上 | 增大日志文件,优化大事务 |

| MEMORY_ALLOCATION_EXT | 等待内存分配 | 内存压力,大查询需要内存授予 | 调整max server memory,优化大排序/哈希 |

查询当前等待统计


-- 查看自上次重启以来的等待累积

SELECT wait_type, waiting_tasks_count, wait_time_ms,

&#x20;      max_wait_time_ms, signal_wait_time_ms,

&#x20;      (wait_time_ms - signal_wait_time_ms) AS resource_wait_ms,

&#x20;      CAST(wait_time_ms * 1.0 / SUM(wait_time_ms) OVER() AS DECIMAL(5,2)) AS pct

FROM sys.dm_os_wait_stats

WHERE wait_type NOT LIKE '%SLEEP%'  -- 过滤无意义等待

&#x20; AND wait_type NOT LIKE '%BROKER%'

&#x20; AND wait_type NOT LIKE '%QUEUE%'

&#x20; AND wait_time_ms > 0

ORDER BY wait_time_ms DESC;

现象解释

  • 为什么重启后性能短暂变好?sys.dm_os_wait_stats 被重置,但根本问题依然存在。

  • 为什么 CXPACKET 等待在并行度高的服务器上正常?少量 CXPACKET 正常,超过15%表示并行不平衡。

3. 系统化优化流程:5步法


步骤1:定位瓶颈(等待统计分析)

&#x20;   ↓

步骤2:关联到具体资源(CPU/内存/IO/网络)

&#x20;   ↓

步骤3:找到消耗资源最多的查询

&#x20;   ↓

步骤4:分析查询执行计划

&#x20;   ↓

步骤5:实施优化并验证效果

步骤1:定位瓶颈 —— 等待统计分析


-- 快速诊断当前瓶颈类型

SELECT 

&#x20;   CASE 

&#x20;       WHEN SUM(wait_time_ms) > 0 THEN 

&#x20;           (SELECT TOP 1 wait_type 

&#x20;            FROM sys.dm_os_wait_stats 

&#x20;            WHERE wait_type NOT LIKE '%SLEEP%' 

&#x20;              AND wait_type NOT LIKE '%BROKER%'

&#x20;            ORDER BY wait_time_ms DESC)

&#x20;       ELSE 'No significant waits'

&#x20;   END AS top_wait_type,

&#x20;   (SELECT SUM(wait_time_ms) FROM sys.dm_os_wait_stats 

&#x20;    WHERE wait_type NOT LIKE '%SLEEP%') AS total_wait_ms;

瓶颈分类决策树


TOP等待类型分析

├─ PAGEIOLATCH_* 主导 (>40%)

│   └─ 内存不足 或 I/O子系统慢 → 检查PLE、磁盘延迟

├─ WRITELOG 主导 (>30%)

│   └─ 日志写入瓶颈 → 检查事务大小、日志盘IOPS

├─ SOS_SCHEDULER_YIELD 主导 (>20%)

│   └─ CPU压力 → 检查CPU使用率、高查询

├─ LCK_M_* 主导 (>20%)

│   └─ 锁阻塞 → 检查孤岛事务、死锁

├─ LATCH_* 主导 (>15%)

│   └─ 内部竞争 → 检查tempdb、数据库页争用

└─ 无明显单一主导(分散)

&#x20;   └─ 混合负载正常,或整体压力大

步骤2:关联到具体资源指标

| 瓶颈类型 | 检查计数器 | 正常值 | 异常值 |

|———-|————|——–|——–|

| CPU | Processor Time, SQL Compilations/sec | 90% 持续 |

| 内存 | Page Life Expectancy, Buffer Cache Hit Ratio | >300秒, >95% | <60秒, <90% |

| 磁盘I/O | Avg Disk Sec/Read, Avg Disk Sec/Write | 50ms |

| 网络 | Network Interface Bytes/sec | 稳定 | 持续满载 |

| 锁阻塞 | Average Wait Time (ms) | 500ms |


-- 内存压力诊断

SELECT 

&#x20;   [name] AS counter_name,

&#x20;   CASE [counter_name]

&#x20;       WHEN 'Page life expectancy' THEN 

&#x20;           CASE WHEN cntr_value < 300 THEN '临界' WHEN cntr_value < 1000 THEN '警告' ELSE '正常' END

&#x20;       WHEN 'Buffer cache hit ratio' THEN 

&#x20;           CASE WHEN cntr_value < 90 THEN '临界' WHEN cntr_value < 95 THEN '警告' ELSE '正常' END

&#x20;   END AS status,

&#x20;   cntr_value

FROM sys.dm_os_performance_counters

WHERE [object_name] LIKE '%Buffer Manager%'

&#x20; AND counter_name IN ('Page life expectancy', 'Buffer cache hit ratio');

步骤3:找到消耗资源最多的查询


-- 当前正在运行的查询(按CPU/IO排序)

SELECT TOP 10 

&#x20;   r.session_id, r.cpu_time, r.total_elapsed_time,

&#x20;   r.logical_reads, r.writes, s.text AS query_text

FROM sys.dm_exec_requests r

CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) s

WHERE r.session_id > 50  -- 排除系统会话

ORDER BY r.cpu_time DESC;  -- 或 logical_reads, writes

-- 历史消耗统计(自上次重启)

SELECT TOP 10 

&#x20;   qs.total_worker_time / qs.execution_count AS avg_cpu,

&#x20;   qs.total_logical_reads / qs.execution_count AS avg_logical_reads,

&#x20;   qs.execution_count, qs.total_elapsed_time,

&#x20;   SUBSTRING(st.text, (qs.statement_start_offset/2)+1,

&#x20;       ((CASE qs.statement_end_offset

&#x20;           WHEN -1 THEN DATALENGTH(st.text)

&#x20;           ELSE qs.statement_end_offset

&#x20;       END - qs.statement_start_offset)/2) + 1) AS query_text

FROM sys.dm_exec_query_stats qs

CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st

ORDER BY qs.total_worker_time DESC;  -- 或 logical_reads, elapsed_time

步骤4:分析执行计划

快速检查清单:

  • [ ] 是否有表扫描?预期行数大吗?

  • [ ] 估计行数 vs 实际行数差异 >10倍?

  • [ ] 是否有书签查找(Key Lookup)且占比高?

  • [ ] 是否有隐式转换(CONVERT_IMPLICIT)?

  • [ ] 连接方式合理吗(小表驱动大表)?

  • [ ] 是否有排序操作且无索引支持?

步骤5:实施优化并验证

优化类型优先级:


1. 查询重写(代价最低,效果可能最大)

&#x20;  - SARGable改造

&#x20;  - 消除隐式转换

&#x20;  - 拆分复杂查询

2. 索引优化(性价比最高)

&#x20;  - 添加覆盖索引

&#x20;  - 调整索引列顺序

&#x20;  - 删除无用索引

3. 配置调整(需谨慎)

&#x20;  - MAXDOP, Cost Threshold for Parallelism

&#x20;  - Max Server Memory

&#x20;  - 隔离级别(RCSI)

4. 硬件升级(最后手段)

&#x20;  - 增加内存

&#x20;  - 换成SSD

&#x20;  - 增加CPU核心

4. 关键性能计数器详解

CPU相关

| 计数器 | 意义 | 告警阈值 |

|——–|——|———-|

| Processor Time | CPU总体使用率 | >80% |

| SQL Compilations/sec | 编译次数(每秒) | >100 |

| SQL Recompilations/sec | 重编译次数 | >10 |

| Batch Requests/sec | 批请求数(吞吐量) | 趋势监控,突然下降可能问题 |

内存相关

| 计数器 | 意义 | 告警阈值 |

|——–|——|———-|

| Page Life Expectancy | 页在内存停留秒数 | <300秒 |

| Buffer Cache Hit Ratio | 缓冲池命中率 | <95% |

| Memory Grants Pending | 等待内存授予的查询数 | >0 |

| Target Server Memory vs Total Server Memory | 预期 vs 实际内存 | 实际 < 目标 持续 |

磁盘I/O相关

| 计数器 | 意义 | 告警阈值 |

|——–|——|———-|

| Avg Disk sec/Read | 平均读延迟 | >20ms(数据),>5ms(日志) |

| Avg Disk sec/Write | 平均写延迟 | >20ms(数据),>5ms(日志) |

| Disk Reads/sec | 每秒读次数 | 与硬件能力对比 |

| Disk Writes/sec | 每秒写次数 | 与硬件能力对比 |

监控脚本(快速健康检查)


-- 一键诊断(运行以上关键指标)

SELECT 'CPU Pressure' AS metric,

&#x20;   CASE WHEN cntr_value > 80 THEN 'HIGH' ELSE 'NORMAL' END AS status,

&#x20;   cntr_value AS value

FROM sys.dm_os_performance_counters

WHERE counter_name = 'Processor Time' AND instance_name = '_Total'

UNION ALL

SELECT 'Memory Pressure',

&#x20;   CASE WHEN cntr_value < 300 THEN 'HIGH' ELSE 'NORMAL' END,

&#x20;   cntr_value

FROM sys.dm_os_performance_counters

WHERE counter_name = 'Page life expectancy'

5. 常用DMV速查表

| 目的 | DMV/函数 |

|——|———-|

| 等待统计 | sys.dm_os_wait_stats |

| 当前请求 | sys.dm_exec_requests |

| 当前会话 | sys.dm_exec_sessions |

| 锁状态 | sys.dm_tran_locks |

| 查询统计(历史)| sys.dm_exec_query_stats |

| 查询计划 | sys.dm_exec_query_plan() |

| 索引使用 | sys.dm_db_index_usage_stats |

| 缺失索引 | sys.dm_db_missing_index_details |

| 计划缓存 | sys.dm_exec_cached_plans |

| 性能计数器 | sys.dm_os_performance_counters |

| 操作系统 | sys.dm_os_sys_info, sys.dm_os_windows_info |

6. 性能优化实战案例

案例1:突然变慢的报表查询

现象:每天早上8-10点报表慢,其他时间正常。

排查过程:

  1. 查等待统计:PAGEIOLATCH_SH 占70%

  2. 定位查询:大表扫描 + 书签查找

  3. 原因:统计信息每天凌晨更新,但查询模式改变

  4. 解决方案:添加覆盖索引,消除书签查找

  5. 验证:执行时间从2分钟降到3秒

案例2:偶发死锁

现象:每月几次死锁错误(1205),重试后成功。

排查过程:

  1. 启用TF1222捕获死锁图

  2. 分析死锁图:两个事务交叉更新同一表的不同行

  3. 原因:非聚集索引书签查找导致锁顺序不一致

  4. 解决方案:统一更新顺序(ORDER BY),添加覆盖索引

  5. 验证:监控一个月,死锁消失

案例3:CPU持续99%

现象:CPU长时间跑满,响应变慢。

排查过程:

  1. 查等待统计:SOS_SCHEDULER_YIELD 占60%

  2. 找高CPU查询:多个查询存在隐式转换

  3. 原因:WHERE VARCHAR列 = 数字,强制全表扫描

  4. 解决方案:统一参数类型,修改索引

  5. 验证:CPU降至40%,业务恢复正常

7. 性能优化的常见陷阱

| 陷阱 | 错误做法 | 正确做法 |

|——|———-|———-|

| 过早优化 | 随便加索引,不管写入影响 | 先分析瓶颈,确认收益>成本 |

| 只看平均 | 平均延迟正常就认为没问题 | 关注P95、P99峰值 |

| 忽视基线 | 不知道正常时什么样 | 建立性能基线,对比异常 |

| 一次改太多 | 同时改索引、查询、配置 | 逐一改动,验证效果 |

| 生产直调 | 直接在生产调参 | 仿真环境验证完整流程 |

| 只看SQL Server | 忽略OS、网络、存储 | 全链路排查 |

8. 建立性能基线

基线内容

  • 业务负载特征:每秒批请求数、并发会话数

  • 等待类型分布:TOP5等待占比

  • 资源使用:CPU、内存、磁盘I/O平均值和峰值

  • 关键查询:TOP10 CPU/IO查询的平均执行时间

  • 业务指标:核心事务响应时间的P50/P95/P99

工具推荐

  • 内置报表:SQL Server 标准报表(右键数据库 → 报表)

  • Performance Dashboard:SQL Server 官方DMV仪表盘

  • sp_Blitz:Brent Ozar 开源诊断工具

  • sp_WhoIsActive:实时监控当前活动(Adam Machanic)


-- 安装 sp_WhoIsActive(推荐)

-- 下载地址:http://whoisactive.com

EXEC sp_WhoIsActive @get_plans = 1, @get_locks = 1;

9. 优化前中后的检查清单

优化前

  • [ ] 收集当前性能指标(等待统计、计数器、基线)

  • [ ] 确认问题范围(全局/特定库/特定查询)

  • [ ] 找到最可能的瓶颈类型

  • [ ] 设计优化方案(含回滚计划)

  • [ ] 评估优化风险(锁、停机时间)

优化中

  • [ ] 在非生产环境验证

  • [ ] 监控优化过程中的关键指标

  • [ ] 记录改动前后对比

  • [ ] 准备回滚脚本

优化后

  • [ ] 验证业务指标改善

  • [ ] 监控副作用(其他查询是否变慢)

  • [ ] 更新文档和基线

  • [ ] 通知团队优化结果


第十期小结

性能优化不是玄学,而是一套可复用的方法论:等待统计定位瓶颈 → 资源指标确认 → 找到消耗查询 → 分析执行计划 → 实施验证。关键工具是sys.dm_os_wait_statssys.dm_exec_query_stats和性能计数器。建立基线和遵循优化流程,能让你从“碰运气”变成“有据可依”。记住:性能优化的第一原则是度量,而不是猜测


整个系列总结

这十期内容覆盖了SQL Server基础架构的核心知识:

| 期数 | 主题 | 核心要点 |

|——|——|———-|

| 第一期 | 整体架构 | 实例、数据库、文件组、执行引擎vs存储引擎 |

| 第二期 | 缓冲池与内存 | Page Life Expectancy、Checkpoint、LazyWriter |

| 第三期 | 事务日志与WAL | VLF、WAL、崩溃恢复(分析+重做+撤消) |

| 第四期 | 索引物理存储 | 堆、聚集/非聚集索引、覆盖索引、书签查找 |

| 第五期 | 并发控制(上) | 隔离级别、锁类型、锁升级、阻塞分析 |

| 第六期 | 并发控制(下) | 死锁检测、死锁分析、消除策略 |

| 第七期 | 查询优化器 | 执行计划、统计信息、参数嗅探 |

| 第八期 | 事务内部实现 | LSN、行版本控制、ARIES恢复 |

| 第九期 | 高可用与DR | 日志传送、复制、Always On AG |

| 第十期 | 性能调优方法论 | 等待统计、DMV分析、系统化流程 |

这十期构成了SQL Server基础架构的知识骨架,帮助你理解现象本质、定位问题根源、制定优化方案。后续可深入学习的方向包括:查询优化器高级话题、分区表与列存储、内存优化表、Azure SQL数据库架构等。

Star
Donate
第九期:高可用与灾难恢复 —— 日志传送、复制、Always On
Previous
AI晨报·第17期|中国牵头AI网络安全国际标准、GPT-5.5正式发布、国家超算互联网平台全面免费开放
Next

Leave a comment

Registration is not required

Clyde Jin
302 Articles
0 Comments
0 Like
Recent Posts

HiddenMerit Daily · Issue 59

📊 HiddenMerit Daily · Issue 59 Focus on Database Frontiers, Practical Insights for DBAs July 21, 2026 | 5 Selected Global Breaking News 01|Oracle Issues Urgent Warning: July 21 Release Update to Fix Large Number of High‑Risk Vulnerabilities, Immediate Deployment Recommended On July 13, Oracle issued an urgent security warning, strongly recommending that all customers running supported Oracle Database versions (including Oracle Database 19c and Oracle AI Database 26ai) immediately test and deploy the Release Update (RU) after its release on July 21. Background: New frontier AI models are significantly lowering the barrier to discovering and exploiting software vulnerabilities – these models can identify weaknesses, analyse software changes, reverse‑engineer security patches, and develop potential attack paths at unprecedented speed and scale. AI models are also becoming increasingly adept at combining multiple weaknesses across the application and data stack into complex attacks, even when individual weaknesses do not themselves pose a serious risk. As a result, protecting systems solely at the network or application layer is no longer sufficient; enterprises must protect the entire technology stack. Fixes Included in This RU: Oracle has collaborated with state‑of‑the‑art models from Anthropic and OpenAI to proactively identify and fix potential security vulnerabilities. The upcoming […]

HiddenMerit Daily · Issue 58

📊 HiddenMerit Daily · Issue 58 Focus on Database Frontiers, Practical Insights for DBAs July 20, 2026 | 5 Selected Global Breaking News 01|CAICT: Domestic Databases Enter Core System “Deep Water,” AI‑Native Leads New Industry Landscape On July 9, at the 2026 Trustworthy Database Development Conference, CAICT released the “Database Development Research Report (2026).” The report notes that domestic databases have basically completed peripheral system replacement and have officially entered the critical business system breakthrough phase. Key Data: The global database market reached $131.6 billion in 2025 (approximately RMB 894.09 billion). The Chinese database market reached $9.49 billion in 2025 (approximately RMB 64.48 billion), and is expected to reach RMB 97.974 billion by 2028, with a CAGR of 13.06%. The number of domestic database vendors has shrunk from a peak of 167 to 94, with a clear head‑concentration effect and an intensifying “Matthew effect.” AI‑Native Becomes the Main Theme: The report points out that database technology is accelerating its evolution toward the AI‑native direction, and the global database industry is entering a new phase of landscape restructuring. The role of databases is upgrading from “underlying support systems” to “core engines enabling intelligent decision‑making and business innovation.” AI agents are becoming […]

HiddenMerit Daily · Issue 56

📊 HiddenMerit Daily · Issue 56 Focus on Database Frontiers, Practical Insights for DBAs July 6, 2026 | 5 Selected Global Breaking News 01|Kingware Releases Manufacturing Scenario Database Evolution White Paper: SQL Server Replacement Enters “Deep Water” On July 5, CETC Kingware published a technical article titled “Database Evolution in Manufacturing Scenarios: How Kingware Replaces SQL Server,” pointing out that the data surge on industrial shop floors has exceeded the processing capacity of single‑node systems. Traditional database architectures that rely on vertical scaling are facing unprecedented performance challenges. Over the next 1‑3 years, manufacturing enterprises will no longer face only the “choice of replacement,” but must answer the strategic question: “How do we build an autonomous data foundation in the context of de‑IOE?” Three Paradigm Shifts: Hybrid Workloads Become the Norm: The IT architecture of modern factories is shifting from separated OLTP and OLAP to HTAP mode. The same data system must simultaneously handle tens of thousands of device instruction writes per second and minute‑level production report analysis. Distributed Architecture Becomes a Hard Requirement: When a single table exceeds 100 million rows with daily increments exceeding 1 million rows, the index maintenance cost of traditional single‑node databases rises exponentially. Autonomous […]

HiddenMerit Daily · Issue 57

📊 HiddenMerit Daily · Issue 57 Focus on Database Frontiers, Practical Insights for DBAs July 17, 2026 | 5 Selected Global Breaking News 01|CAICT Releases “Database Development Research Report (2026)”: China Market to Reach RMB 98 Billion by 2028, AI‑Native Becomes the Main Theme On July 9, at the 2026 Trustworthy Database Development Conference, the China Academy of Information and Communications Technology (CAICT) officially released the “Database Development Research Report (2026),” comprehensively revealing the latest landscape and evolution directions of the global and Chinese database markets. Key Data: Global Market: The global database market reached $131.6 billion in 2025 (approximately RMB 894.09 billion). Chinese Market: The Chinese database market reached $9.49 billion in 2025 (approximately RMB 64.48 billion), accounting for 7.2% of the global market. By 2028, the total Chinese database market is expected to reach RMB 97.974 billion, with a compound annual growth rate of 13.06% . Industry Landscape: There are 394 database product providers globally, with China and the US leading in vendor count. The number of global open‑source and closed‑source products is roughly balanced. Commercial databases account for over 70% in China, while the proportion of open‑source databases is increasing. After rapid growth from 2022 to 2024, […]
生成中...
扫描二维码
扫描二维码