You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL 11.6未始终使用索引咨询:查询order_status=1走全表扫描

问题解答

没错,就是因为order_status = 1的行占比过高,PostgreSQL查询优化器判定全表扫描的执行成本比使用B-tree索引更低,所以选择了顺序扫描。

具体原因分析

  1. 数据占比计算
    全表总行数为:197739 + 465879 + 59133 + 4883 = 727634,其中order_status = 1的行数占比约为64%,超过了表中一半以上的数据。

  2. 索引与全表扫描的成本差异

    • 使用B-tree索引时,需要先通过索引定位到目标行的物理位置,再执行回表操作读取完整行数据,这个过程涉及随机IO,当需要返回的行数过多时,随机IO的开销会急剧上升。
    • 全表扫描是顺序读取所有数据,虽然会读取不需要的行,但顺序IO的效率远高于随机IO,对于占比极高的数据集,整体成本反而更低。
  3. 优化器的决策逻辑
    PostgreSQL优化器会依赖表的统计信息(你给出的各状态行数统计就是核心依据)估算执行成本,当查询返回的行数占表总行数的比例超过阈值(通常经验值在10%-20%左右,具体取决于表结构、存储介质等),就会优先选择全表扫描。

验证方法

你可以通过以下方式验证这个结论:

  • 执行EXPLAIN ANALYZE select * from tbl_order where order_status = 1;,查看执行计划中的成本估算和实际执行耗时。
  • 强制关闭全表扫描:SET enable_seqscan = off;,再执行相同查询,对比强制走索引后的执行耗时,会发现全表扫描确实更快。

内容的提问来源于stack exchange,提问作者sffortytwo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 09:53:37