首页 / 后端开发 / PostgreSQL性能调优与索引优

PostgreSQL性能调优与索引优化实战:用EXPLAIN把慢查询从2.8秒降到118毫秒

Roxi
Roxi 加速器 — 稳定·快速·安全
全球节点覆盖,支持所有主流平台,一键连接无需配置。新用户免费试用。
立即体验 →

CHAPTER 1|先定位:别凭感觉给数据库加索引

SEO 基础优化内容策略规划外链体系建设技术架构升级转化漏斗分析

大家好,这次我们直接打开终端实战!OK,页面慢不代表一定缺索引,先抓出真正耗时的SQL。开发环境可以启用统计扩展:

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

SELECT query,
       calls,
       total_exec_time,
       mean_exec_time,
       rows
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

如果只想临时捕获超过500毫秒的请求,可以调整日志:

ALTER SYSTEM SET log_min_duration_statement = '500ms';
SELECT pg_reload_conf();

接下来对目标SQL执行计划。注意一定要使用真实参数,EXPLAIN ANALYZE会实际执行查询;线上UPDATE或DELETE先改成SELECT验证。

EXPLAIN (ANALYZE, BUFFERS, VERBOSE)
SELECT id, total_amount
FROM orders
WHERE user_id = 1024
  AND status = 'paid'
ORDER BY created_at DESC
LIMIT 20;

屏幕上重点看三项:Seq Scan表示全表扫描,actual time是实际耗时,Buffers里的shared read越高说明磁盘读取越多。我的测试表有1200万行,原计划扫描全表,耗时2.84秒。

CHAPTER 2|动手改:联合索引要匹配过滤与排序

85%转化提升2.5s响应速度100+功能模块365天持续更新

这条查询先按user_id和status过滤,再按created_at倒序取最新记录,所以索引顺序不能乱:

CREATE INDEX CONCURRENTLY idx_orders_user_status_created
ON orders (user_id, status, created_at DESC)
INCLUDE (id, total_amount);

CREATE INDEX CONCURRENTLY不会长时间阻塞正常读写,但会增加构建时间和磁盘占用;执行前确认剩余空间至少能容纳索引大小。建完后更新统计信息:

ANALYZE orders;

EXPLAIN (ANALYZE, BUFFERS)
SELECT id, total_amount
FROM orders
WHERE user_id = 1024
  AND status = 'paid'
ORDER BY created_at DESC
LIMIT 20;

现在观察是否出现Index Scan或Index Only Scan。我的实测结果从2.84秒降到118毫秒,shared hit明显增加,shared read大幅下降。不要给每一列都建单列索引:索引会拖慢INSERT、UPDATE,并增加VACUUM压力。

还有三个常见坑:LIKE '%phone%'通常无法使用普通B-tree索引;对字段包函数,如WHERE LOWER(email)=...,应建立表达式索引;低区分度字段单独建索引收益很小。模糊搜索可评估:

CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE INDEX CONCURRENTLY idx_users_name_trgm
ON users USING gin (name gin_trgm_ops);

CHAPTER 3|验证与收尾:确认快了,而不是“看起来快了”

先连续执行同一SQL 20次,分别记录平均延迟、P95延迟和Buffers;第一次可能包含冷缓存,不能作为唯一结论。再检查表膨胀和自动清理状态:

SELECT relname, n_live_tup, n_dead_tup,
       last_analyze, last_autovacuum
FROM pg_stat_user_tables
WHERE relname = 'orders';

如果n_dead_tup持续升高,检查autovacuum阈值,不要直接把work_mem调到很大;它按连接和算子消耗内存,高并发下容易反噬。修复完成的标准是:执行计划稳定使用合适索引,20次测试平均延迟低于目标,P95没有明显抖动,且写入吞吐未下降。

你也可以把自己的EXPLAIN结果贴出来一起拆解;如果需要额外的网络访问工具,Roxi只是可选方案,免费、官方或自建路线同样可以先完成数据库调优。