PostgreSQL SELECT查询未使用预期联合索引user_account_id_deleted_at_idx问题
原因分析
- 匹配行数极少导致过滤成本可忽略
从执行计划可以看到,account_id = '00000010005009'条件仅匹配到1行数据,使用单列索引查到这行后,再做deleted_at IS NULL的过滤操作CPU成本几乎为0。单列索引比联合索引体积更小,扫描需要的IO开销更低,优化器计算成本后自然会选择成本更低的单列索引。 - 数据分布与统计信息的影响
如果该account_id对应的记录里,deleted_at为NULL的占比极高,优化器会认为过滤条件几乎不会筛掉数据,不需要用联合索引来降低过滤成本。如果表统计信息长时间未更新,也可能导致优化器估算偏差,可执行ANALYZE "user";更新统计信息后再验证。 - 索引存储特性的差异
单列索引user_account_id_idx仅存储account_id的值,联合索引user_account_id_deleted_at_idx需要存储两个字段的值,相同数据量下联合索引占用更多磁盘页,扫描IO开销更高,在过滤成本可以忽略的场景下,单列索引的综合成本更低。
操作正误说明
你没有操作错误,这是PostgreSQL优化器基于成本计算的正常选择,不属于使用失误。
如果业务中绝大多数查询都会携带deleted_at IS NULL的过滤条件,你可以直接删除冗余的单列索引user_account_id_idx,优化器会自动选择联合索引执行查询,同时还能节省索引占用的存储空间和数据写入时的索引维护成本。
内容的提问来源于stack exchange,提问作者Aman Patel
相关产品推荐
相关产品推荐

