索引、执行计划与调优
索引类型与选择
Tip
部分索引(Partial Index) 是 PG 的独门利器:当某类查询只涉及很小比例的行(如 status='pending'),部分索引的体积和写入成本都远低于全表索引。
读懂 EXPLAIN ANALYZE
要点:
cost=起始..总代价 rows=预估行数 width=;actual time=... rows=... loops=...是实测值。- 预估行数与实际行数差异巨大 → 统计信息不准或相关性误判,需
ANALYZE或调default_statistics_target。 - 关注扫描方式:
Seq Scan(全表)、Index Scan、Index Only Scan(覆盖)、Bitmap Heap Scan。 - 关注连接方式:
Nested Loop、Hash Join、Merge Join。 BUFFERS显示缓存命中:shared read高说明磁盘 I/O 多。
VACUUM 与自动清理
PG 的 MVCC 会让 UPDATE/DELETE 产生死元组,需要 VACUUM 回收;autovacuum 默认开启自动处理。
Warning
大量 UPDATE/DELETE 却不清理会导致表膨胀、扫描变慢、事务 ID 回卷(wraparound)风险。对写频繁的大表,务必确认 autovacuum 能跟上,必要时应手动调优其触发阈值。VACUUM FULL 会锁表,生产环境优先使用 pg_repack 在线整理。
关键参数调优
Tip
优先用连接池而不是堆 max_connections。PG 每个连接是一个进程,开销远大于 MySQL 线程。推荐 PgBouncer 或应用侧 pgxpool,把连接数控制在合理范围。
小结
- 索引按场景选型:B-Tree 通用,GIN 管多值,BRIN 管有序大表,部分/覆盖索引省空间。
EXPLAIN ANALYZE的预估 vs 实际行数是诊断第一现场。- 关注死元组与膨胀,确保
autovacuum跟得上写入。 - 调参前先解决索引与 SQL 问题;连接层面用池化。