用途
PostgreSQLPerf 是一份用于 PostgreSQL 数据库的性能优化与最佳实践参考,适用于编写 SQL 查询、设计数据库模式(schema)、实现索引,或排查数据库性能问题的场景。内容以“优先级”为主线组织,从严重程度高的规则到较低优先级的规则依次给出建议与代码示例。
主要能力与规则
严重(CRITICAL):查询性能
- 避免在无索引列上做 WHERE 过滤,示例中为 orders 表的 customer_email 列创建索引:
-- ❌ 无索引的 WHERE
SELECT * FROM orders WHERE customer_email = 'user@example.com';
-- ✅ 创建索引
CREATE INDEX idx_orders_email ON orders(customer_email);
- 养成使用 EXPLAIN ANALYZE 的习惯,始终查看执行计划。
- 大表上出现 Seq Scan 时,说明需要索引。
- 禁止 SELECT *,只选择需要的列。
- 将 N+1 查询替换为 JOIN 或批量查询。
严重(CRITICAL):连接管理
- 使用连接池,不要直接建立连接。
- Supabase 场景使用 pgBouncer(transaction 模式)。
- Serverless 环境必须使用连接池。
- 清理空闲连接。
高(HIGH):模式设计
- 避免不加区分地创建索引,例如不要把大量列塞进一个复合索引。
- 对高频条件使用部分索引:
-- ❌ 无节制的索引
CREATE INDEX idx_everything ON orders(a, b, c, d, e);
-- ✅ 部分索引(针对常用条件)
CREATE INDEX idx_active_orders ON orders(created_at)
WHERE status = 'active';
- 范式化与非范式化:根据读取模式决定。
- UUID 与 serial:UUID 在分布式环境中更有利,但索引体积更大。
- JSONB:仅用于无法结构化的数据;如果字段需要被查询,应改为独立列。
中(MEDIUM):并发与锁
- 大批量 UPDATE/DELETE 采用批处理方式。
- 使用 SELECT ... FOR UPDATE 时只锁定需要的行。
- 尽量缩短事务。
- 通过一致的加锁顺序防止死锁。
低(LOW):行级安全(RLS)
- 给出安全策略示例:
-- 安全策略示例
CREATE POLICY user_data ON user_profiles
FOR SELECT USING (auth.uid() = user_id);
- RLS 策略要与索引一起设计,因为这会影响性能。
- 尽量减少 auth.uid() 调用。
- 对复杂策略用 EXPLAIN 检查性能。
使用方式与实操提示
- 开发阶段:使用 EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)。
- 生产环境:启用慢查询日志。
- 迁移:对大表执行 ALTER 时采用异步方式。
- 备份:可在 NAS 上自动化执行 pg_dump。 上述代码示例与命令均保留原文写法,按资料原文呈现。
适用场景
适合在编写 SQL 时评估索引与查询写法、设计表结构时权衡索引与字段类型、排查慢查询与执行计划、配置数据库连接方式、处理批量写入与锁竞争,以及设计 RLS 策略时参考。
限制
资料未提供具体的版本兼容范围、性能基准数据、完整示例项目或工具链集成信息,这些方面暂未提供。