SQL优化作为DBA日常主要工作内容,分析SQL的执行计划,是必须要掌握的知识点。执行计划体现了SQL在数据库中的执行方式,SQL语句按照什么样的方式执行,是由优化器决定的。达梦数据库也是一样,SQL语句是由优化器设计执行方式的。达梦数据库提供了2个命令来进行分析SQL的执行计划,分别为explain和explain for,下面我们分别进行介绍。
1、使用EXPLAIN分析执行计划
达梦数据库提供explain命令查看SQL的执行计划,命令使用语法格式为:EXPLAIN <SQL 语句>;
执行计划显示方式与Oracle类似,执行计划的执行顺序也是与Oracle类似,如果能看懂Oracle数据库的执行计划,看达梦数据库的执行计划就非常容易了,主要的难度就是达梦数据库SQL执行计划的操作符与Oracle是不一样的,达梦数据库也是提供了V$SQL_NODE_NAME视图,供大家查看每个操作符的含义,当然,也可以直接去官方手册《DM8系统管理员手册》-附录4执行计划操作符章节来查每个操作符的含义。达梦数据库SQL执行计划的执行过程为:控制流从上到下传递,数据流从下到上传递。

1 #NSET2: [0, 16, 9]
2   #PRJT2: [0, 16, 9]; EXP_NUM(2), IS_ATOM(FALSE)
3     #NEST LOOP INDEX JOIN2: [0, 16, 9]
4       #CSCN2: [0, 4, 5]; INDEX33555535(B)
5       #SSEK2: [0, 4, 0]; SCAN_TYPE(ASC), IDX_T1_C1 (A),
SCAN_RANGE[T2.D1,T2.D1]

例如,如上的执行计划大致执行流程如下:

  1. CSCN2: 扫描 T2 表的聚集索引,数据传递给父节点索引连接;
  2. NEST LOOP INDEX JOIN2: 当左孩子有数据返回时取右侧数据;
  3. SSEK2: 利用 T2 表当前的 D1 值作为二级索引 IDX_T1_C1 定位查找的 KEY,返回结果给父节点;
  4. NEST LOOP INDEX JOIN2: 如果右孩子有数据则将结果传递给父节点 PRJT2,否则继续取左孩子的下一条记录;
  5. PRJT2: 进行表达式计算 C1+1, D2;
  6. NSET2: 输出最后结果;
  7. 重复过程 1) ~ 4)直至左侧 CSCN2 数据全部取完。
    2、使用EXPLAIN FOR分析执行计划
    EXPLAIN FOR 语句也用于查看 SQL语句的执行计划,不过执行计划以结果集的方式返回。EXPLAIN FOR 显示的执行计划信息相比于EXPLAIN更加丰富,除了常规计划信息,还包括创建索引建议、分区表的起止分区信息等。重要的是,语句的计划保存在数据表中,方便用户随时查看,进行计划对比分析,可以作为性能分析的一种方法。
    语法格式为:EXPLAIN [AS 计划名称] FOR <SQL 语句>;
    需要注意的是,explain for将语句的执行计划保存在"SYSDBA"."##PLAN_TABLE"表中,而这个表是个临时表,且是会话级的,如果需要永久保存执行计划,需要将该表中的信息转储到其他永久表中,如下是该表的创建语句,从语句末尾可以看到给表的属性。
CREATE GLOBAL TEMPORARY TABLE "SYSDBA"."##PLAN_TABLE"
(
"PLAN_ID" INT,
"PLAN_NAME" VARCHAR(128),
"CREATE_TIME" DATETIME(6),
"LEVEL_ID" INT,
"OPERATION" VARCHAR(30),
"TAB_NAME" VARCHAR(128),
"IDX_NAME" VARCHAR(128),
"SCAN_TYPE" VARCHAR(20),
"SCAN_RANGE" VARCHAR(128),
"ROW_NUMS" BIGINT,
"BYTES" INT,
"COST" BIGINT,
"CPU_COST" BIGINT,
"IO_COST" BIGINT,
"FILTER" VARCHAR(1000),
"JOIN_COND" VARCHAR(1000),
"ADVICE_INFO" VARCHAR(1000),
"PSTART" INT,
"PSTOP" INT)
ON COMMIT PRESERVE ROWS STORAGE(ON TEMP);

ON COMMIT PRESERVE ROWS:指定临时表是会话级的,会话结束时会清空表。