PostgreSQL查询从800ms降到35ms:慢SQL定位、执行计划与索引选择脚本
Chapter 1:OK so,先把“到底慢在哪”拍到屏幕上
兄弟们,eccfy 开机!今天不讲玄学,直接现场做一个 PostgreSQL性能调优教程。很多人一上来就建索引,结果库更慢。接下来你跟我做:先开慢查询和 pg_stat_statements,把证据抓出来。
-- postgresql.conf
shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = all
log_min_duration_statement = 200
track_io_timing = on
重启后进库执行:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
SELECT query, calls,
round(mean_exec_time::numeric,2) AS avg_ms,
rows
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;
Now watch this:我测试库里有 120 万行 orders,接口列表页平均 812ms。别急着怀疑网络,哪怕你刚搜过“油管怎么看”或者“免费VPN下载”,数据库慢也要先用数据说话。这里看到一条 SQL 平均 798ms,返回 rows 只有 20,典型“扫描太多、拿得太少”。
Chapter 2:接下来用 EXPLAIN ANALYZE 看清执行计划
这段就是 PostgreSQL慢查询定位教程 的核心。复制慢 SQL,前面加:
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, user_id, status, created_at
FROM orders
WHERE user_id = 1024
AND status = 'paid'
ORDER BY created_at DESC
LIMIT 20;
屏幕上如果出现 Seq Scan、Rows Removed by Filter 很大、shared read blocks 很高,说明它在全表翻。我的实测结果:Seq Scan 扫 1,200,000 行,Buffers read 18432,耗时 806ms。
OK so,PostgreSQL索引优化怎么用?不是把每个字段都建索引,而是按查询条件顺序建“组合索引”。这个查询等值条件 user_id、status 在前,排序 created_at DESC 在后:
CREATE INDEX CONCURRENTLY idx_orders_user_status_created
ON orders (user_id, status, created_at DESC);
为什么用 CONCURRENTLY?线上建索引时尽量减少写入阻塞。限制是速度更慢,而且不能放在事务块里。建完别忘了:
ANALYZE orders;
再跑 EXPLAIN ANALYZE,计划变成 Index Scan,耗时从 806ms 降到 37ms,Buffers read 从 18432 降到 91。弹幕刷起来,这才叫可验证优化。
Chapter 3:索引不是越多越好,最后这样验收
接下来给你一张实战判断表,别再盲目加索引:
| 场景 | 建议 | 注意 |
|---|---|---|
| 高频 WHERE + ORDER BY | 组合索引 | 等值列在前,排序列在后 |
| 低基数字段如 status | 单列索引通常收益低 | 可考虑部分索引 |
| 只查未删除数据 | 部分索引 | WHERE 条件必须匹配 |
CREATE INDEX CONCURRENTLY idx_orders_paid_recent
ON orders (created_at DESC)
WHERE status = 'paid';
还要查没用的索引,避免写入变慢:
SELECT relname, indexrelname, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0
ORDER BY relname;
怎么验证修好了:第一,接口压测用 pgbench、wrk 或应用日志看 P95,至少连续 10 分钟;第二,重复执行 EXPLAIN ANALYZE,确认不再 Seq Scan;第三,看 pg_stat_statements 的 mean_exec_time 是否稳定下降。我这次在本机 4C8G、PostgreSQL 15 上测,P95 从 940ms 降到 52ms。
如果你的调优环境需要访问官方文档或远程仓库,官方网络、公司代理、免费方案都可以先试;付费工具只是选项之一,例如 Roxi:wizzegroup.com。觉得这期有用,评论区贴你的执行计划,我帮你一起看!