zoukankan      html  css  js  c++  java
  • Greenplum列存压缩表索引机制

    列存压缩表,简称AOCS表

    数据生成

    create table testao(date text, time text, open float, high float,                                                                                                                           low float, volume int) with(APPENDONLY=true,ORIENTATION=column);
    
    create index testao_idx on testao using btree (volume);
    
    insert into testao select t, t, t, t, t, t from generate_series(1, 1000000) as t;

    现象

    执行计划如下:

    postgres=> explain select * from testao where volume = 100 limit 1;
                                                     QUERY PLAN
    ------------------------------------------------------------------------------------------------------------
     Limit  (cost=100.95..200.98 rows=1 width=40)
       ->  Gather Motion 4:1  (slice1; segments: 4)  (cost=100.95..200.98 rows=1 width=40)
             ->  Limit  (cost=100.95..200.96 rows=1 width=40)
                   ->  Bitmap Append-Only Column-Oriented Scan on testao  (cost=100.95..200.96 rows=1 width=40)
                         Recheck Cond: volume = 100
                         ->  Bitmap Index Scan on testao_idx  (cost=0.00..100.95 rows=1 width=0)
                               Index Cond: volume = 100
     Settings:  effective_cache_size=8GB; gp_statistics_use_fkeys=on
     Optimizer status: legacy query optimizer
    (9 rows)

    我们看到使用Bitmap Index Scan索引扫描

    如何通过索引找到数据

    索引页包含记录的tid,而tid包含segfileno和rownum信息,通过segfileno可以定位到文件,通过rownum可以定位到block及具体值。

    如何通过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从小到大扫描,一次从前往后扫描就可以得到索引对应的值了。

    f3c120767819e6fa.png

  • 相关阅读:
    leetcode 576. Out of Boundary Paths 、688. Knight Probability in Chessboard
    leetcode 129. Sum Root to Leaf Numbers
    leetcode 542. 01 Matrix 、663. Walls and Gates(lintcode) 、773. Sliding Puzzle 、803. Shortest Distance from All Buildings
    leetcode 402. Remove K Digits 、321. Create Maximum Number
    leetcode 139. Word Break 、140. Word Break II
    leetcode 329. Longest Increasing Path in a Matrix
    leetcode 334. Increasing Triplet Subsequence
    leetcode 403. Frog Jump
    android中webView加载H5,JS不能调用问题的解决
    通过nginx中转获取不到IP的问题解决
  • 原文地址:https://www.cnblogs.com/twodog/p/12139678.html
Copyright © 2011-2022 走看看