第二十一章 性能调优实战 - 第三节 实战:电商平台高峰期性能瓶颈排查
文章目录
第三节 实战:电商平台高峰期性能瓶颈排查
目标:通过模拟一次电商平台在促销活动期间遇到的性能瓶颈,实践一套系统化的慢查询定位、分析和优化流程,综合运用
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
子句中的精确匹配和范围匹配列创建复合索引。1
CREATE INDEX idx_products_category_stock ON products (category_id, in_stock);
- 文本搜索索引:使用
pg_trgm
扩展来处理模糊LIKE
查询。1 2
CREATE EXTENSION IF NOT EXISTS pg_trgm; CREATE INDEX idx_products_desc_trgm ON products USING GIN (description gin_trgm_ops);
- 排序索引:为
ORDER BY
的列创建索引。1
CREATE 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
,确认优化措施生效,并量化性能提升的效果。
这套方法论是每个数据库管理员和后端开发者都应掌握的核心技能,它能帮助你在系统面临性能压力时,有条不紊地解决问题,保障服务的稳定。