数据库性能治理:从慢查询到容量规划
数据库性能治理不是临时加索引,而是围绕慢查询、执行计划、索引、连接池、热点、容量和压测建立持续机制。
数据库性能治理:从慢查询到容量规划
数据库性能问题很少是突然出现的。更多时候,它是在业务增长、查询变复杂、数据量变大、索引失控、连接数上涨的过程中慢慢积累出来的。
性能治理不是救火,而是建立一套持续观察、分析、优化和预防机制。
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% 才扩容。数据库扩容和迁移往往需要准备窗口。
小结
数据库性能治理的顺序通常是:
- 先监控。
- 再定位慢查询。
- 看执行计划。
- 调整 SQL 和索引。
- 验证收益。
- 做容量规划和长期治理。
性能优化不是一次性动作,而是工程纪律。