PostgreSQL 完全指南 / 22 - 最佳实践
第 22 章 · 最佳实践
本章汇总生产环境的连接池策略、SQL 编码规范、VACUUM 策略和上线 Checklist。
22.1 连接池最佳实践
| 参数 |
推荐值 |
说明 |
PgBouncer pool_mode |
transaction |
最高复用率 |
default_pool_size |
20-50 |
每个数据库的连接池大小 |
max_client_conn |
1000-5000 |
最大客户端连接数 |
server_idle_timeout |
300-600 |
空闲后端连接超时 |
server_lifetime |
3600 |
后端连接最大生存时间 |
PG max_connections |
200-500 |
不超过 500 |
应用连接数 = max_client_conn (PgBouncer)
实际 PG 连接数 = default_pool_size × 数据库数
22.2 SQL 编码规范
命名规范
| 对象 |
规则 |
示例 |
| 表名 |
小写 + 下划线 |
user_orders |
| 列名 |
小写 + 下划线 |
created_at |
| 主键 |
id 或 表名_id |
id, order_id |
| 外键 |
引用表名_id |
customer_id |
| 索引 |
idx_表名_列名 |
idx_orders_customer |
| 唯一索引 |
uniq_表名_列名 |
uniq_users_email |
| 约束 |
chk_表名_描述 |
chk_orders_positive_amount |
| 触发器 |
trg_表名_事件 |
trg_users_update_timestamp |
| 函数 |
小写 + 下划线 |
calculate_total() |
SQL 编写规范
-- ✅ 关键字大写
SELECT id, name, email
FROM users
WHERE is_active = TRUE
ORDER BY created_at DESC
LIMIT 20;
-- ✅ 使用显式列名,避免 SELECT *
SELECT id, name, email FROM users;
-- ✅ 使用参数化查询,避免 SQL 注入
-- cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
-- ✅ 使用 TIMESTAMPTZ
CREATE TABLE events (
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
);
-- ✅ 外键必须有索引
CREATE TABLE orders (
customer_id INT REFERENCES customers(id)
);
CREATE INDEX idx_orders_customer ON orders (customer_id);
-- ✅ 大批量操作使用事务
BEGIN;
INSERT INTO ...;
INSERT INTO ...;
COMMIT;
-- ✅ 使用 EXPLAIN ANALYZE 验证慢查询
22.3 VACUUM 策略
autovacuum 配置
# postgresql.conf
autovacuum = on
autovacuum_max_workers = 3 # 并行工作者数
autovacuum_naptime = 1min # 检查间隔
autovacuum_vacuum_threshold = 50 # 最少死行数
autovacuum_vacuum_scale_factor = 0.1 # 死行比例(10%)
autovacuum_analyze_threshold = 50
autovacuum_analyze_scale_factor = 0.05 # 分析阈值(5%)
autovacuum_vacuum_cost_delay = 2ms # IO 限制延迟
autovacuum_vacuum_cost_limit = 200 # IO 限制
大表特殊配置
-- 为大表设置更低的触发阈值
ALTER TABLE large_table SET (
autovacuum_vacuum_scale_factor = 0.01, -- 1% 死行就触发
autovacuum_analyze_scale_factor = 0.005,
autovacuum_vacuum_cost_delay = 0 -- 不限速
);
监控 VACUUM
-- 查看表的 VACUUM 状态
SELECT
relname,
n_live_tup,
n_dead_tup,
round(n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0) * 100, 2) AS dead_pct,
last_vacuum,
last_autovacuum,
last_analyze,
last_autoanalyze
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;
-- 查看正在进行的 VACUUM
SELECT pid, query, state, wait_event_type, wait_event
FROM pg_stat_activity
WHERE query LIKE 'autovacuum:%';
22.4 生产环境 Checklist
部署前
| ☐ |
检查项 |
| ☐ |
PostgreSQL 版本为最新稳定版 |
| ☐ |
shared_buffers 设置为总内存的 25% |
| ☐ |
effective_cache_size 设置为总内存的 75% |
| ☐ |
work_mem 合理设置(4-64MB) |
| ☐ |
max_connections 不超过 500 |
| ☐ |
wal_level = replica |
| ☐ |
random_page_cost = 1.1(SSD) |
| ☐ |
log_min_duration_statement = 1000(记录慢查询) |
| ☐ |
autovacuum 已启用并正确配置 |
| ☐ |
pg_hba.conf 安全配置(无 trust) |
| ☐ |
SSL 已启用 |
| ☐ |
复制用户权限最小化 |
运维中
| ☐ |
检查项 |
| ☐ |
每日备份验证 |
| ☐ |
监控复制延迟 |
| ☐ |
监控表膨胀率 |
| ☐ |
监控连接数 |
| ☐ |
监控缓存命中率 |
| ☐ |
定期 ANALYZE |
| ☐ |
定期清理无用索引 |
| ☐ |
事务 ID 年龄监控 |
| ☐ |
WAL 文件数量监控 |
| ☐ |
慢查询定期审查 |
22.5 配置参数速查
| 参数 |
4GB 内存 |
16GB 内存 |
64GB 内存 |
shared_buffers |
1GB |
4GB |
16GB |
effective_cache_size |
3GB |
12GB |
48GB |
work_mem |
8MB |
32MB |
64MB |
maintenance_work_mem |
256MB |
1GB |
2GB |
wal_buffers |
64MB |
64MB |
64MB |
max_connections |
200 |
300 |
500 |
max_wal_size |
2GB |
4GB |
8GB |
random_page_cost |
1.1 |
1.1 |
1.1 |
业务场景
| 场景 |
建议 |
| 新项目上线 |
参照 Checklist 逐项检查 |
| 性能调优 |
pg_stat_statements + EXPLAIN ANALYZE |
| 容量规划 |
监控增长趋势 + 压测拐点 |
| 事故复盘 |
日志 + pg_stat_activity + 锁信息 |
扩展阅读