SQL 执行计划的展示是了解 SQL 执行逻辑和性能调优的最重要的手段。用户可以通过 explain 命令查看优化器针对给定SQL 生成的逻辑执行计划。在执行 explain 命令时,系统会为给定的 SQL 生成最终的逻辑执行计划并展示给用户,但并不会生成相应的物理执行计划(可执行的代码),也不会真正执行该计划或者将该计划放入计划缓存。
Explain 命令格式
Explain 命令格式如下例所示,展示的格式包括 BASIC、EXTENDED、PARTITIONS 等。
EXPLAIN [BASIC | EXTENDED | PARTITIONS | FORMAT = format_name] explainable_stmt
format_name: { TRADITIONAL | JSON }
explainable_stmt: { SELECT statement
| DELETE statement
| INSERT statement
| REPLACE statement
| UPDATE statement }
计划形状与算子信息
Explain 输出的第一部分是执行计划的树形结构展示。其中每一个操作在树中的层次通过其在 OPERATOR 中的缩进予以展示。如下例所示:
|==========================================
|ID|OPERATOR |NAME|EST. ROWS|COST|
------------------------------------------
|0 |SORT | |1 |2763|
|1 | MERGE INNER JOIN| |1 |2735|
|2 | SORT | |1000 |1686|
|3 | TABLE SCAN |t2 |1000 |1180|
|4 | TABLE SCAN |t1 |1 |815 |
==========================================
其对应的树状执行计划如下图所示:
执行计划中的各项的含义如下:
列名 | 含义 |
ID | 执行树按照前序遍历的方式得到的编号(从0开始) |
OPERATOR | 操作算子的名称 |
NAME | 对应表操作的表名(索引名) |
EST. ROWS | 估算的该操作算子的输出行数 |
COST | 该操作算子的执行代价(微秒) |
在表操作中,NAME 字段会显示该操作涉及的表的名称(别名),如果是使用索引访问,还会在名称后的括号中展示该索引的名称, 例如 t1(t1_c2) 表示使用了 t1_c2 这个索引。另外,如果扫描的顺序是逆序,还会在后面使用 reserve 关键字标识,例如 t1(t1_c2,Reverse)。
一些常见的算子类型归纳如下表:
类型 | 算子 |
表访问 | table scan, table get |
连接 | NESTED-LOOP, BLK-NESTED-LOOP,Merge、hash |
排序 | sort,top-n sort |
聚合 | merge group-by,hash group-by, window function |
分布式 | exchange in/out remote/distribute |
集合 | union, except, intersect,minus |
其他 | limit, material, subplan, expression, count |
操作算子详细输出
Explain 输出的第二部分是各操作算子的详细信息,包括输出表达式、过滤条件、分区信息以及各算子的独有信息,包括排序键、连接键、下压条件等。
Outputs & filters:
-------------------------------------
0 - output([t1.c1], [t1.c2], [t2.c1], [t2.c2]), filter(nil), sort_keys([t1.c1, ASC], [t1.c2, ASC]), prefix_pos(1)
1 - output([t1.c1], [t1.c2], [t2.c1], [t2.c2]), filter(nil),
equal_conds([t1.c1 = t2.c2]), other_conds(nil)
2 - output([t2.c1], [t2.c2]), filter(nil), sort_keys([t2.c2, ASC])
3 - output([t2.c2], [t2.c1]), filter(nil),
access([t2.c2], [t2.c1]), partitions(p0)
4 - output([t1.c1], [t1.c2]), filter(nil),
access([t1.c1], [t1.c2]), partitions(p0)
一些常用的信息含义如下表:
信息名称 | 含义 |
output | 该算子的输出表达式列表 |
filter | 该算子执行的过滤条件 |
access | 表访问中存储层的投影列名 |
partitions | 分区裁剪的信息 |
sort_keys | 排序操作的排序键 |
prefix_pos | 局部有序的偏移位置 |
equal_conds | 连接操作中执行的等值连接条件 |
other_conds | 连接操作中执行的非等值连接条件 |