OceanBase 理解执行计划

索引回表

在 OceanBase 数据库 v4.1 中,对于普通索引和全局索引,索引回表的逻辑都封装在TABLE SCAN 算子中的。在执行计划展示时,会有 is_index_back 标识算子是否需要回表,以及 is_global_index 标识算子是否是扫描全局索引。

示例

如下示例为包含 TABLE SCAN 算子的执行计划。

  1. 创建 ts_ny 表。

    obclient> CREATE TABLE ts_ny(c1 NUMBER PRIMARY KEY,c2 NUMBER,c3 NUMBER,c4 NUMBER,INDEX K5(c2));
    Query OK, 0 rows affected
    
  2. 查看详细的执行计划。

    obclient> EXPLAIN EXTENDED SELECT * FROM ts_ny WHERE c1 = 1\G
    *************************** 1. row ***************************
    Query Plan: ===================================
    |ID|OPERATOR |NAME |EST. ROWS|COST|
    -----------------------------------
    |0 |TABLE GET|TS_NY|1        |46  |
    ===================================
    
    Outputs & filters:
    -------------------------------------
      0 - output([TS_NY.C1(0x7f9d9ffe0020)], [TS_NY.C2(0x7f9d9ffe03d0)], [TS_NY.C3(0x7f9d9ffe06c0)], [TS_NY.C4(0x7f9d9ffe09b0)]), filter(nil),
          access([TS_NY.C1(0x7f9d9ffe0020)], [TS_NY.C2(0x7f9d9ffe03d0)], [TS_NY.C3(0x7f9d9ffe06c0)], [TS_NY.C4(0x7f9d9ffe09b0)]), partitions(p0),
          is_index_back=false,
          range_key([TS_NY.C1(0x7f9d9ffe0020)]), range[1 ; 1],
          range_cond([TS_NY.C1(0x7f9d9ffe0020) = 1(0x7f9d9ffdf900)])
    
    Used Hint:
    -------------------------------------
      /*+
      */
    
    Outline Data:
    -------------------------------------
      /*+
          BEGIN_OUTLINE_DATA
          FULL(@"SEL$1" "SYS.TS_NY"@"SEL$1")
          END_OUTLINE_DATA
      */
    
    Plan Type:
    -------------------------------------
    LOCAL
    
    Optimization Info:
    -------------------------------------
    
    TS_NY:table_rows:100000, physical_range_rows:1, logical_range_rows:1, index_back_rows:0, output_rows:1, est_method:default_stat, optimization_method=rule_based, heuristic_rule=unique_index_without_indexback
    
    Parameters
    -------------------------------------
    
    1 row in set
    

如下示例为包含 TABLE SCAN 算子的全局索引回表的执行计划。

  1. 创建 tl_ny 表。

    obclient>  CREATE TABLE tl_ny(c1 NUMBER PRIMARY KEY, c2 NUMBER, c3 NUMBER) PARTITION BY
               HASH(c1) PARTITIONS 4;
    Query OK, 0 rows affected
    
  2. 创建全局索引 tin

    obclient> CREATE INDEX tin ON tl_ny(c2) GLOBAL;
    Query OK, 0 rows affected
    
  3. 查看执行计划。

    obclient> EXPLAIN SELECT * FROM tl_ny WHERE c2 = 1;
    +---------------------------------------------------------------------------+
    | Query Plan                                                                |
    +---------------------------------------------------------------------------+
    | ============================================================              |
    | |ID|OPERATOR              |NAME      |EST.ROWS|EST.TIME(us)|              |
    | ------------------------------------------------------------              |
    | |0 |DISTRIBUTED TABLE SCAN|TL_NY(TIN)|1       |28          |              |
    | ============================================================              |
    | Outputs & filters:                                                        |
    | -------------------------------------                                     |
    |   0 - output([TL_NY.C1], [TL_NY.C2], [TL_NY.C3]), filter(nil), rowset=256 |
    |       access([TL_NY.C1], [TL_NY.C2], [TL_NY.C3]), partitions(p0)          |
    |       is_index_back=true, is_global_index=true,                           |
    |       range_key([TL_NY.C2], [TL_NY.C1]), range(1,MIN ; 1,MAX),            |
    |       range_cond([TL_NY.C2 = 1])                                          |
    +---------------------------------------------------------------------------+
    12 rows in set (0.00 sec)
    

参数解释

参数解释

上述示例中,执行计划展示中的 outputs & filters 详细展示了 TABLE SCAN 算子的输出信息,其含义如下表所示。

信息名称含义
operatorTABLE SCAN 算子的 operator 有两种形式:TABLE SCAN 和 TABLE GET
  • TABLE SCAN 属于范围扫描,返回 0 行或者多行数据。
  • TABLE GET 直接用主键定位,返回 0 行或者 1 行数据。
name选择用哪个索引来访问数据。选择的索引的名字会跟在表名后面,如果没有索引的名字,则说明执行的是主表扫描。 这里需要注意,在 OceanBase 数据库中,主表和索引的组织结构是一样的,主表本身也是一个索引。更多信息,可以参考 索引的存储
output该算子的输出列。
filter该算子的过滤谓词。
partitions查询需要扫描的分区。
is_index_back该算子是否需要回表。
is_global_index该算子是否是扫描全局索引。
filter_before_indexback与每个 filter 对应,表明该 filter 是可以直接在索引上进行计算,还是需要索引回表之后才能计算。
range_key/range/range_cond
  • range_key:索引的 rowkey 列。
  • range:索引开始扫描和结束扫描的位置。判断是否是全表扫描需要关注 range 的范围。例如,对于一个 rowkey 有三列的场景,range(MIN,MIN, MIN ; MAX, MAX, MAX) 代表的就是真正意义上的全表扫描。
  • range_cond:决定索引开始扫描和结束扫描位置的相关谓词。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值