列存压缩表,简称aocs表
执行计划如下:
我们看到使用bitmap index scan索引扫描
索引页包含记录的tid,而tid包含segfileno和rownum信息,通过segfileno可以定位到文件,通过rownum可以定位到block及具体值。
对于索引,gp将会创建一个pg_aoblkdi_oid辅助表(block directory),里面包含每个block在文件的偏移位置fileoffset、segfileno、firstrownum,并在firstrownum列上创建索引,只要给出一个rownum,通过索引在pg_aoblkdi_oid辅助表中可以快速得到block在文件的偏移位置fileoffset,然后取出数据。
为什么aocs表使用的索引方法是bitmap index scan,而不是我们常见的index scan呢?
ao表的扫描方向只能从前往后,而不能从后往前,heap表从前往后、从后往前都是支持的。通过索引找到的数据在ao文件位置并不是从前往后顺序的。如图所示,假设我们的条件是id<=7,通过索引找到的记录的顺序是1,3,5,7。如果是index scan,那么就要先从fileoffset位置扫描到第三个位置找到value=1,然后继续扫描到第四个位置value=3,然后继续从fileoffset位置开始扫描第一个位置value=5,继续扫描到第二个位置value=7,可以看到使用index scan可能会有多次回头重新开始扫描,增加了io。为了避免这个问题,只使用bitmap index scan,将会先扫描所有满足索引的值,然后按照tid排序,按照rownum从小到大扫描,一次从前往后扫描就可以得到索引对应的值了。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLhZmNllTM4cjN3AjMxM2Mm9CX5UjN0MzLcdmbw9CXrJXYsl3az9CXldWYtlWL59GbwVGZz1mctkXYwlGbh9CXt92YukXYwlGbh5yc0NWZqJ2b5FGcpxWYtUGdhZXayB3Lc9CX6MHc0RHaiojIsJye.png)