什么让索引有用
email 上的索引具有高选择性,因为大多数值唯一;active(true/false)则很低:查询活跃用户可能读取大部分表,规划器可能选择顺序扫描。
-- 高选择性:缩小到一行或少数行
CREATE INDEX orders_customer_created_idx
ON orders (customer_id, created_at DESC);
-- 单列低选择性;作为部分索引更有效
CREATE INDEX orders_pending_idx
ON orders (created_at)
WHERE status = 'pending';
复合索引顺序很重要
对于 WHERE tenant_id = $1 AND status = $2 ORDER BY created_at DESC,(tenant_id, status, created_at) 可以同时服务过滤与排序;(status, tenant_id, created_at) 在 status 低选择性时可能无法有效缩小范围。
测量而非猜测
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders WHERE customer_id = $1 ORDER BY created_at DESC LIMIT 20;
关注索引扫描的 buffers 与行数。如果规划器选择顺序扫描,用 ANALYZE 更新统计信息,并比较实际行数与估算值。
何时添加索引
当查询频繁、选择性强且对延迟敏感时添加索引。与反规范化相比,索引保留数据模型但增加写入开销;与缓存相比,它优化源查询而不是复制结果。
陷阱
索引占用存储并拖慢插入、更新与删除。未使用的索引是纯开销,应审查使用统计。对索引列使用函数会阻止索引,除非建立匹配的表达式索引。用接近生产的数据分布测试;小表很少触发真实的规划器选择。