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

PostgreSQL查询计划未显示Table2堆访问的原因咨询

这是个很棒的问题!你观察到的现象其实是PostgreSQL几个核心特性共同作用的结果,我来一步步拆解给你看:

1. 二级索引自动包含主键列

PostgreSQL的所有二级索引都会自动附加表的主键列作为行定位器——因为你的Table2主键是id,所以你创建的ix_Table2_groupby_orderby索引实际包含的列是:groupby, orderby, id。这是PostgreSQL的默认行为,原本是为了让索引条目能快速定位到堆中的对应行,但这里它刚好帮了我们另一个大忙。

2. 查询所需列可通过索引列推导

看你填充Table2的脚本,查询中需要的其余列都能通过索引已有的列直接计算得出:

  • local_search = orderby % 50:索引里有orderby字段,直接计算即可
  • global_search = id % 1000:索引里包含主键id,直接取模就能得到
  • padding = RPAD('Value ' || id || ' ', 100, '*'):用索引里的id就能生成这个填充字符串

PostgreSQL的查询优化器能识别出这些计算逻辑,直接在索引扫描阶段就完成所有列的计算,完全不需要去访问堆里的实际数据行。

3. 可见性映射(VM)让索引-only扫描成为可能

因为你的表是刚创建并批量插入数据的,还没有发生过任何删除或更新操作,PostgreSQL的可见性映射(Visibility Map)会标记这些数据页面为"全可见"。这意味着PostgreSQL可以安全地使用索引-only扫描——不需要访问堆来检查行的可见性(所有行对当前事务都是可见的)。这就是为什么EXPLAIN ANALYZE和EXPLAIN VERBOSE都看不到堆访问记录的原因。

如果之后你对Table2执行了更新/删除操作,且没有运行VACUUM来更新可见性映射,那么查询可能就需要访问堆来确认行的可见性了。


内容的提问来源于stack exchange,提问作者Radim Bača

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:43:20