由于Explain并不会真正执行给定的 SQL,用户一般可以放心使用该功能而不用担心在性能调试中可能给系统性能带来影响。也正是因为没有真正执行 SQL,Explain 所展示的计划是在执行命令时优化器根据当前的用户输入和数据统计信息所生成的逻辑执行计划,而并不是在计划缓存中真正被使用的物理执行计划(二者在某些场景下可能会有不同)。展示计划缓存中的物理计划的方式请参考章节。

Explain 命令格式如下例所示,展示的格式包括 BASIC、EXTENDED、PARTITIONS 等等,内容的详细程度有所区别。

Explain 输出的第一部分是执行计划的树形结构展示。其中每一个操作在树中的层次通过其在 OPERATOR 中的缩进予以展示。如下例所示的执行计划:

其对应的树状执行计划如下图所示:

在表操作中,NAME 字段会显示该操作涉及的表的名称(别名),如果是使用索引访问,还会在名称后的括号中展示该索引的名称, 例如 t1(t1_c2) 表示使用了 t1_c2 这个索引。另外,如果扫描的顺序是逆序,还会在后面使用 reserve 关键字标识,例如 t1(t1_c2,Reverse)。

一些常见的算子类型归纳如下表:

Explain 输出的第二部分是各操作算子的详细信息,包括输出表达式、过滤条件、分区信息以及各算子的独有信息,包括排序键、连接键、下压条件等。

重点的信息如下:

  • access
    表访问操作中需要调用存储层的接口访问具体的数据,access 展示了存储层的对外输出(投影)列名。

  • partitions
    OceanBase 内部支持二级分区。针对用户 SQL 给定的条件,优化器会将不需要访问的分区过滤掉,这一步骤我们称为分区裁剪。partitions 显式了经过分区裁剪后剩下的分区,其中如果涉及到多个连续分区,例如从分区0到分区20,会按照“起始分区号——结束分区号”的形式展示,例如 partitions(p0-20)。

  • range_key 和 range
    OceanBase 中的物理表理论上都是索引组织表(包括二级索引本身),扫描的时候都会按照一定的顺序进行扫面,这个顺序就是该表的主键,体现在 range_key 中,当用户给定不同条件时,优化器会定位到最终扫描的范围,通过 range 展示,如下例所示的计划:

可以看出要访问的表为 t1_c2 这张索引表,表的主键为 (c2, c1),扫描的范围是全表扫描。

一些常用的信息含义如下表: