第二十一章 性能调优实战 - 第三节 实战:电商平台高峰期性能瓶颈排查
文章目录
第三节 实战:电商平台高峰期性能瓶颈排查
目标:通过模拟一次电商平台在促销活动期间遇到的性能瓶颈,实践一套系统化的慢查询定位、分析和优化流程,综合运用
pg_stat_statements,EXPLAIN, 索引优化和查询重写等核心技能。
场景描述
我们的电商平台正在进行“黑色星期五”大促,网站流量激增。运维团队收到大量告警,用户反馈商品搜索页面加载极慢,甚至出现超时。数据库服务器的 CPU 使用率飙升至 100%。我们的任务是快速定位并解决性能瓶颈。
第一步:初步诊断 (Triage)
当系统出现紧急性能问题时,首先要快速了解“现在正在发生什么”。
1. 查看当前活动的查询
连接到数据库,使用 pg_stat_activity 视图来查看当前正在运行的查询。
| |
我们可能会发现有几条相同的、执行时间非常长的(duration 达到几十秒)的搜索查询处于 active 状态,这为我们提供了第一个线索。
2. 使用 pg_stat_statements 定位“元凶”
pg_stat_activity 只显示当前快照,而 pg_stat_statements 扩展能聚合统计一段时间内所有查询的性能数据,是定位“问题查询”的最有力工具。
(需要预先在 postgresql.conf 中配置 shared_preload_libraries = 'pg_stat_statements' 并 CREATE EXTENSION pg_stat_statements;)
| |
通过这个查询,我们几乎可以肯定地找到那个平均执行时间(mean_exec_time)最长的查询。假设我们找到了如下这条“罪魁祸首”:
问题查询:
| |
第二步:分析执行计划 (EXPLAIN ANALYZE)
我们把这条慢查询拿出来,执行 EXPLAIN ANALYZE 来深入分析它的执行计划。
| |
糟糕的执行计划(示例):
| |
问题分析:
Seq Scan on products: 查询规划器选择了全表扫描,扫描了近百万行数据,这是最主要的问题。Filter: (lower(description) ...): 在description列上使用lower()函数和前导通配符的LIKE,导致无法使用任何标准 B-Tree 索引。Sort Method: external merge Disk: 512MB:ORDER BY操作因为工作内存不足(work_mem太小),不得不使用磁盘进行外部排序,这极大地拖慢了速度。
第三步:实施优化
1. 创建合适的索引
- 复合索引:为
WHERE子句中的精确匹配和范围匹配列创建复合索引。1CREATE INDEX idx_products_category_stock ON products (category_id, in_stock); - 文本搜索索引:使用
pg_trgm扩展来处理模糊LIKE查询。1 2CREATE EXTENSION IF NOT EXISTS pg_trgm; CREATE INDEX idx_products_desc_trgm ON products USING GIN (description gin_trgm_ops); - 排序索引:为
ORDER BY的列创建索引。1CREATE INDEX idx_products_created_at_desc ON products (created_at DESC);
2. 重写查询
修改查询以利用新创建的 pg_trgm 索引。注意,pg_trgm 默认是大小写不敏感的,所以可以去掉 lower() 函数。
| |
3. 调整配置 (可选)
如果磁盘排序问题依然存在,可以考虑适度增加 work_mem。但通常在创建了合适的 ORDER BY 索引后,排序本身的开销会大大减少。
第四步:验证优化效果
再次对优化后的查询执行 EXPLAIN ANALYZE。
理想的执行计划:
| |
效果分析:
Index Scan: 查询规划器现在使用了最高效的索引扫描。- 没有
Sort节点: 因为ORDER BY的顺序与idx_products_created_at_desc索引的顺序一致,PostgreSQL 可以直接从索引中按顺序读取数据,完全避免了排序操作。 - 执行时间:从 4.5 秒骤降至 0.3 毫秒,性能提升了上万倍!
📌 小结
本次实战演练了一套完整、系统化的性能瓶颈排查流程:
- 监控与定位:使用
pg_stat_activity和pg_stat_statements快速找到消耗资源最多的问题查询。 - 分析与诊断:使用
EXPLAIN ANALYZE深入剖析查询的执行计划,找出Seq Scan、磁盘排序等性能瓶颈。 - 优化与实施:针对性地创建复合索引、函数索引(如
pg_trgm)和排序索引,并重写查询以利用这些索引。 - 验证与对比:再次执行
EXPLAIN ANALYZE,确认优化措施生效,并量化性能提升的效果。
这套方法论是每个数据库管理员和后端开发者都应掌握的核心技能,它能帮助你在系统面临性能压力时,有条不紊地解决问题,保障服务的稳定。
