首页 / 后端开发 / PostgreSQL查询从800ms

PostgreSQL查询从800ms降到35ms:慢SQL定位、执行计划与索引选择脚本

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

Chapter 1:OK so,先把“到底慢在哪”拍到屏幕上

📋STEP 1环境搭建🔧STEP 2编码实现🚀STEP 3测试验证✅STEP 4部署上线

兄弟们,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 看清执行计划

2020行业萌芽2021快速增长2022竞争加剧2023洗牌整合2024成熟稳定

这段就是 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。觉得这期有用,评论区贴你的执行计划,我帮你一起看!