索引回表
在 OceanBase 数据库 v4.1 中,对于普通索引和全局索引,索引回表的逻辑都封装在TABLE SCAN
算子中的。在执行计划展示时,会有 is_index_back
标识算子是否需要回表,以及 is_global_index
标识算子是否是扫描全局索引。
示例
如下示例为包含 TABLE SCAN
算子的执行计划。
-
创建
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
-
查看详细的执行计划。
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
算子的全局索引回表的执行计划。
-
创建
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
-
创建全局索引
tin
。obclient> CREATE INDEX tin ON tl_ny(c2) GLOBAL; Query OK, 0 rows affected
-
查看执行计划。
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
算子的输出信息,其含义如下表所示。
信息名称 | 含义 |
---|---|
operator | TABLE SCAN 算子的 operator 有两种形式:TABLE SCAN 和 TABLE GET 。
|
name | 选择用哪个索引来访问数据。选择的索引的名字会跟在表名后面,如果没有索引的名字,则说明执行的是主表扫描。 这里需要注意,在 OceanBase 数据库中,主表和索引的组织结构是一样的,主表本身也是一个索引。更多信息,可以参考 索引的存储。 |
output | 该算子的输出列。 |
filter | 该算子的过滤谓词。 |
partitions | 查询需要扫描的分区。 |
is_index_back | 该算子是否需要回表。 |
is_global_index | 该算子是否是扫描全局索引。 |
filter_before_indexback | 与每个 filter 对应,表明该 filter 是可以直接在索引上进行计算,还是需要索引回表之后才能计算。 |
range_key/range/range_cond |
|