数据库性能治理:从慢查询到容量规划

数据库性能治理不是临时加索引,而是围绕慢查询、执行计划、索引、连接池、热点、容量和压测建立持续机制。

数据库性能治理:从慢查询到容量规划

数据库性能问题很少是突然出现的。更多时候,它是在业务增长、查询变复杂、数据量变大、索引失控、连接数上涨的过程中慢慢积累出来的。

性能治理不是救火,而是建立一套持续观察、分析、优化和预防机制。

Rendering diagram...

慢查询治理

慢查询是性能治理的入口。首先要收集慢 SQL,按总耗时、执行次数、平均耗时、扫描行数排序。

不要只看单次最慢。一个 SQL 单次 500ms,但每天执行一千万次,可能比一个偶发 10s 的 SQL 更值得治理。

执行计划

优化 SQL 前先看执行计划。

EXPLAIN
SELECT *
FROM orders
WHERE user_id = 10001
  AND created_at >= '2026-05-01'
ORDER BY created_at DESC;

执行计划要重点看:

  • 是否使用索引。
  • 扫描行数是否合理。
  • Join 顺序是否合理。
  • 是否出现临时表和文件排序。
  • 估算行数和真实行数是否差异巨大。

索引治理

索引设计要围绕高频查询,而不是围绕字段数量。

组合索引的字段顺序很重要。通常把等值过滤字段放前面,范围字段和排序字段结合查询模式设计。

CREATE INDEX idx_orders_user_created
  ON orders (user_id, created_at);

索引也需要治理冗余。重复索引、长期不用的索引,会浪费空间并拖慢写入。

连接池

数据库连接不是越多越好。连接太多会让数据库线程、内存和调度成本上升,反而降低吞吐。

连接池要设置合理的最大连接数、超时时间、空闲连接数和慢请求保护。应用扩容时,也要同步评估数据库总连接数。

热点行与热点 Key

库存扣减、计数器、账户余额、全局配置,都可能成为热点。

热点行会造成锁竞争。解决方案包括:

  • 拆分计数器。
  • 异步聚合。
  • 使用库存分桶。
  • 降低事务范围。
  • 对高频读加缓存。

分区和归档

数据量变大后,历史数据会拖累查询和维护。

按时间分区可以让数据库快速裁剪不相关数据。历史订单、日志、流水、消息表都适合考虑分区或归档。

CREATE TABLE order_logs (
  id BIGINT,
  created_at DATE NOT NULL,
  content TEXT
) PARTITION BY RANGE (created_at);

分区不是银弹。如果查询不带分区键,分区裁剪就发挥不出来。

容量规划

容量规划要看趋势:

  • 数据量增长速度。
  • QPS 和 TPS。
  • 磁盘使用率。
  • Buffer 命中率。
  • 主从延迟。
  • 慢查询数量。
  • 峰值连接数。

不要等磁盘 95% 才处理,也不要等主库 CPU 长期 90% 才扩容。数据库扩容和迁移往往需要准备窗口。

小结

数据库性能治理的顺序通常是:

  1. 先监控。
  2. 再定位慢查询。
  3. 看执行计划。
  4. 调整 SQL 和索引。
  5. 验证收益。
  6. 做容量规划和长期治理。

性能优化不是一次性动作,而是工程纪律。

参考链接