注册
达梦DM8使用disql查看执行计划的6种方法
专栏/培训园地/ 文章详情 /

达梦DM8使用disql查看执行计划的6种方法

dmwwei 2023/10/23 2424 0 0
摘要

1、概述

如果有安装达梦客户端的环境,建议使用达梦数据库客户端工具:DM管理工具(manager)进行图形化连接达梦数据库,并通过任务栏选择“显示执行计划(P)(F9)”查看SQL语句的执行计划。

如果没有安装达梦客户端的环境,需要通过Xshell等工具连接到数据库服务器,使用命令行工具disql连接到达梦数据库查看SQL语句的执行计划,下文将对disql查看SQL语句执行计划的方法进行说明。

1.1 查看执行计划的方法

1)EXPLAIN
2)EXPLAIN FOR
3)ET
4)set autotrace on
5)cacheplan
6)10053、10003事件

2、方法介绍

1)创建测试数据
create table test1 ( ID INT, NAME varchar2(10));
create table test2 ( ID INT, NAME varchar2(10));

insert into test1 values(1,'小王');
insert into test1 values(2,'小张');
insert into test1 values(3,'小李');
insert into test1 values(4,'小刘');
commit;

insert into test2 values(3,'小王2');
insert into test2 values(4,'小张2');
insert into test2 values(5,'小李2');
insert into test2 values(6,'小刘2');
commit;
2)检查表数据信息
SQL> select * from test1;
ID NAME


1 小王
2 小张
3 小李
4 小刘
已用时间: 1.720(毫秒). 执行号:912.
SQL> select * from test2;
ID NAME


3 小王2
4 小张2
5 小李2
6 小刘2
已用时间: 0.702(毫秒). 执行号:913.
SQL>

2.1 EXPLAIN

EXPLAIN 语句可以查看 DML 语句的执行计划。

1)语法格式
EXPLAIN <SQL 语句>;
<SQL 语句> ::= <删除语句> | <插入语句> | <查询语句> | <更新语句>
2)执行命令
EXPLAIN select t1.,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;
3)执行结果
SQL> EXPLAIN select t1.
,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;

1 #NSET2: [1, 16, 104]
2 #PRJT2: [1, 16, 104]; exp_num(3), is_atom(FALSE)
3 #HASH2 INNER JOIN: [1, 16, 104]; KEY_NUM(1); KEY(T1.ID=T2.ID) KEY_NULL_EQU(0)
4 #CSCN2: [1, 4, 52]; INDEX33555963(TEST1 as T1)
5 #CSCN2: [1, 4, 52]; INDEX33555964(TEST2 as T2)

已用时间: 0.851(毫秒). 执行号:0.
SQL>

2.2 EXPLAIN FOR

EXPLAIN FOR 语句也用于查看 DML 语句的执行计划,不过执行计划以结果集的方式返回。

EXPLAIN FOR 显示的执行计划信息更加丰富,除了常规计划信息,还包括创建索引建议、分区表的起止分区信息等。重要的是,语句的计划保存在数据表中,方便用户随时查看,进行计划对比分析,可以作为性能分析的一种方法。需要注意的是,explain for将语句的执行计划保存在"SYSDBA"."##PLAN_TABLE"表中,而这个表是个临时表,且是会话级的。

1)语法格式
EXPLAIN [AS <计划名称>] FOR <SQL 语句>;
<SQL 语句> ::= <删除语句> | <插入语句> | <查询语句> | <更新语句>
2)执行命令
EXPLAIN FOR select t1.,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;
3)执行结果
SQL> EXPLAIN FOR select t1.
,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;

PLAN_ID PLAN_NAME CREATE_TIME LEVEL_ID OPERATION TAB_NAME IDX_NAME SCAN_TYPE SCAN_RANGE ROW_NUMS BYTES COST CPU_COST


IO_COST FILTER JOIN_COND ADVICE_INFO PSTART PSTOP


1 NULL 2022-11-03 22:12:35.000000 0 NSET2 NULL NULL NULL NULL 16 104 1 0
0 NULL NULL NULL 0 0

1 NULL 2022-11-03 22:12:35.000000 1 PRJT2 NULL NULL NULL NULL 16 104 1 0
0 NULL NULL NULL 0 0

1 NULL 2022-11-03 22:12:35.000000 2 HASH2 INNER JOIN NULL NULL NULL NULL 16 104 1 0
0 NULL NULL NULL 0 0

1 NULL 2022-11-03 22:12:35.000000 3 CSCN2 TEST1 INDEX33555963 NULL NULL 4 52 1 0
0 NULL NULL NULL 0 0

1 NULL 2022-11-03 22:12:35.000000 3 CSCN2 TEST2 INDEX33555964 NULL NULL 4 52 1 0
0 NULL NULL NULL 0 0

已用时间: 1.772(毫秒). 执行号:914.
SQL>
说明:字段ADVICE_INFO的内容就是优化建议的信息。

2.3 ET

统计执行 ID 为 ID_IN 的所有操作符的执行时间。

需设置 INI 参数 ENABLE_MONITOR=1、MONITOR_TIME=1 和 MONITOR_SQL_EXEC=1。
CALL SP_SET_PARA_VALUE(1,'ENABLE_MONITOR',1);
CALL SP_SET_PARA_VALUE(1,'MONITOR_TIME',1);
CALL SP_SET_PARA_VALUE(1,'MONITOR_SQL_EXEC',1);

1)语法格式
ET(
ID_IN INT
);
参数说明:
ID_IN:SQL 语句的执行 ID。
2)执行命令
select t1.,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;
Call ET(ID_IN);
3)执行结果
SQL> select t1.
,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;

ID NAME NAME


3 小李 小王2
4 小刘 小张2

已用时间: 1.393(毫秒). 执行号:916.
SQL> Call ET(916);

OP TIME(US) PERCENT RANK SEQ N_ENTER HASH_USED_CELLS HASH_CONFLICT


DLCK 0 0% 6 0 2 0 0
PRJT2 2 0.24% 5 2 4 0 0
CSCN2 9 1.09% 4 4 2 0 0
CSCN2 10 1.21% 3 5 2 0 0
NSET2 31 3.76% 2 1 3 0 0
HI3 772 93.69% 1 3 6 4 0
6 rows got
已用时间: 29.689(毫秒). 执行号:917.
SQL>
说明:OP为对应的操作符,time为执行耗时,以微秒为单位,PERCENT为在整个计划中用时占比,rank为时间排行,SEQ为对应执行计划中的序号,N_ENTER是操作符进入的次数。

2.4 set autotrace on

设置执行计划和统计信息的跟踪。

该功能开启前提是ini参数:ENABLE_MONITOR、MONITOR_SQL_EXEC 已开启。
CALL SP_SET_PARA_VALUE(1,'ENABLE_MONITOR',1);
CALL SP_SET_PARA_VALUE(1,'MONITOR_SQL_EXEC',1);

1)语法格式
SET AUTOTRACE <OFF(默认值) | NL | INDEX | ON|TRACE>
当 SET AUTOTRACE OFF时,停止 AUTOTRACE 功能,常规执行语句。
当 SET AUTOTRACE NL时,开启 AUTOTRACE 功能,不执行语句,如果执行计划中有嵌套循环操作,那么打印NL操作符的内容。
当 SET AUTOTRACE INDEX(或者ON)时,开启 AUTOTRACE 功能,不执行语句,如果有表扫描,那么打印执行计划中表扫描的方式、表名和索引。
当 SET AUTOTRACE TRACE 时,开启 AUTOTRACE 功能,执行语句,打印执行计划。此功能与服务器 EXPLAIN 语句的区别在于,EXPLAIN 只生成执行计划,并不会真正执行 SQL 语句,因此产生的执行计划有可能不准。而 TRACE 获得的执行计划,是服务器实际执行的计划。
2)执行命令
SQL> set autotrace on
SQL> select t1.,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;
3)执行结果
SQL> set autotrace on
SQL> select t1.
,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;

0 | CSCN2 | TEST1 as T1 | INDEX33555963
1 | CSCN2 | TEST2 as T2 | INDEX33555964

已用时间: 0.530(毫秒). 执行号:0.
SQL>

2.5 Cacheplan

通过 PLNDUMP 来看对应缓存中的 SQL 执行计划。

1.语法格式
1)可以直接通过SQL语句匹配:
select cache_item from v$cachepln where sqlstr = ‘%待优化sql%’
2)根据上步骤中获取的cache_item导出plndump
ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME PLNDUMP,LEVEL <查出的CACHE_ITEM>';
3)然后通过trace事件查看trace文件--执行完成后,会在DAMENG目录的trace目录下生成一个trc文件,打开该文件
select * from v$dm_ini where para_name = 'TRACE_PATH';
2.执行命令
SQL> select /* ww_test / t1.,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;
SQL> select * from v$cachepln where sqlstr like '%ww_test%';
SQL> ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME PLNDUMP,LEVEL 140663918319728';
SQL> select * from v$dm_ini where para_name = 'TRACE_PATH';
3.执行结果
SQL> select /* ww_test / t1.,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;

ID NAME NAME


3 小李 小王2
4 小刘 小张2

已用时间: 1.356(毫秒). 执行号:920.
SQL> select * from v$cachepln where sqlstr like '%ww_test%';

CACHE_ITEM TYPE$ HASH_VALUE SCHID USER_ID OBJ_ID RS_CAN_CACHED N_RS_CACHED N_TABLE TABLEID


SQLSTR SQLCACHE DDLSCRIPT RET_CMD STMT_TYPE N_LIT_PARA N_CLNT_PARA N_COLS SEL_UPDATABLE


MEM_SIZE RS_CAN_CACHED_IN_RULE BINDED


140565897480304 SQL 1841085100 150994945 50331649 0 N 0 0 NULL
select * from v$cachepln where sqlstr like '%ww_test%'; 140565931414776 NULL 160 7 0 0 22 N
56744 N N

140565897472112 SQL 643663267 150994945 50331649 0 Y 0 2 1405 1406
select /* ww_test / t1.,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID; 140565931414008 NULL 160 7 0 0 3 N
56744 Y N

已用时间: 0.963(毫秒). 执行号:921.
SQL> ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME PLNDUMP,LEVEL 140565897472112';
操作已执行
已用时间: 2.302(毫秒). 执行号:922.
SQL> select * from v$dm_ini where para_name = 'TRACE_PATH';

PARA_NAME PARA_VALUE MIN_VALUE MAX_VALUE DEFAULT_VALUE MPP_CHK SESS_VALUE FILE_VALUE DESCRIPTION PARA_TYPE


TRACE_PATH /dm8/dmdbms/data/DAMENG/trace NULL NULL NULL N /dm8/dmdbms/data/DAMENG/trace NULL System trace path name READ ONLY

已用时间: 3.377(毫秒). 执行号:923.
SQL> exit
[dmdba@master bin]$ cd /dm8/dmdbms/data/DAMENG/trace
[dmdba@master trace]$ ls -lrt
total 28
-rw-r--r-- 1 dmdba dinstall 803 Nov 3 22:45 dm20221103_0000.trc
[dmdba@master trace]$
[dmdba@master trace]$ more dm20221103_0000.trc
DM Database Server x64 V8
*** 2022-11-03 22:45:33.702000*** start dump the infos of pln[140565897472112].
start dump the infos of pln[140565897472112].
SQL_STR:
select /* ww_test / t1.,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;
PLN_CMD:
0 savepoint
6 dop_try_begin 0
10 dop_try_begin 1
14 sql 0 0
24 nop
26 jmp 67
32 nop
34 push 0
40 swap
42 sloc 1
46 err_set 0
50 rollback
56 jmp 67
62 nop
64 throw dir 1
67 exception end
69 savepoint
75 cop 'b'
79 hlt 0

sqlnode[0]::::
1 #NSET2: [1, 16->2, 104]
2 #PRJT2: [1, 16->2, 104]; exp_num(3), is_atom(FALSE)
3 #HASH2 INNER JOIN: [1, 16->2, 104]; KEY_NUM(1);
4 #CSCN2: [1, 4->4, 52]; INDEX33555963(TEST1)
5 #CSCN2: [1, 4->4, 52]; INDEX33555964(TEST2)

end dump the infos of pln[140565897472112].
[dmdba@master trace]$
说明:此方法也适用于抓取存储过程和函数里面SQL语句的执行计划。

2.6 10053事件

10053 事件,以类似Oracle的方式,提供的一种供用户查看内部优化实现细节的途径,借此观察并了解错误计划的原因。

1)语法格式
alter session set events '10053 trace name context forever, level 1';
EXPLAIN+待优化的sql
alter session set events '10053 trace name context off';
注意:10053 trace SQL语句的计划生成过程输出到TRACE 文件,TRACE出的是SQL 的实际执行计划;生成的TRACE文件默认在数据目录生成trace文件夹,文件以.trc结尾。
2)执行命令
SQL> alter session set events '10053 trace name context forever, level 1';
SQL> EXPLAIN select t1.,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;
SQL> alter session set events '10053 trace name context off';
SQL> select * from v$dm_ini where para_name = 'TRACE_PATH';
3)执行结果
SQL> alter session set events '10053 trace name context forever, level 1';
操作已执行
已用时间: 13.786(毫秒). 执行号:1000.
SQL> EXPLAIN select t1.
,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;

1 #NSET2: [1, 16, 104]
2 #PRJT2: [1, 16, 104]; exp_num(3), is_atom(FALSE)
3 #HASH2 INNER JOIN: [1, 16, 104]; KEY_NUM(1); KEY(T1.ID=T2.ID) KEY_NULL_EQU(0)
4 #CSCN2: [1, 4, 52]; INDEX33555963(TEST1 as T1)
5 #CSCN2: [1, 4, 52]; INDEX33555964(TEST2 as T2)

已用时间: 1.153(毫秒). 执行号:0.
SQL> alter session set events '10053 trace name context off';
操作已执行
已用时间: 0.432(毫秒). 执行号:1001.
SQL> select * from v$dm_ini where para_name = 'TRACE_PATH';

PARA_NAME PARA_VALUE MIN_VALUE MAX_VALUE DEFAULT_VALUE MPP_CHK SESS_VALUE FILE_VALUE DESCRIPTION PARA_TYPE


TRACE_PATH /dm8/dmdbms/data/DAMENG/trace NULL NULL NULL N /dm8/dmdbms/data/DAMENG/trace NULL System trace path name READ ONLY

已用时间: 13.261(毫秒). 执行号:1002.
SQL> exit
[dmdba@master bin]$ cd /dm8/dmdbms/data/DAMENG/trace
[dmdba@master trace]$ ls -lrt
total 12
-rw-r--r-- 1 dmdba dinstall 11649 Nov 3 22:56 DMSERVER_1103_2256_140568038617328.trc
[dmdba@master trace]$

说明:此SQL语句中有2张表,他会把2张表各种可能的组合都试一遍,并计算出各种资源代价,从而选出代价最小的,也就是执行计划最优的方案来。

2.7 10003事件

只能抓出对应事件的SQL语句。

1)语法格式
--开启全表扫描跟踪
alter session 0 set events '10003 trace name context forever, level N';
--关闭全表扫描跟踪
alter session 0 set events '10003 trace name context off';
--查看trace日志所在的目录
select * from v$dm_ini where para_name = 'TRACE_PATH';
说明:level 支持1到15 含义如下:
LEVEL 1 CSCN
LEVEL 2 HASH JOIN
LEVEL 4 HAGR
LEVR 8 NEST LOOP
支持 这几种操作符号组合,比如TRACE CSCN 和 HASH JOIN 的语句,level 可以设置为3 (1+2)

2)执行命令
SQL> alter session 0 set events '10003 trace name context forever, level 3';
SQL> select t1.,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;
SQL> alter session 0 set events '10003 trace name context off';
SQL> select * from v$dm_ini where para_name = 'TRACE_PATH';
说明:此命令是全局抓取对应要求的SQL语句。
3)执行结果
SQL> alter session 0 set events '10003 trace name context forever, level 3';
操作已执行
已用时间: 0.812(毫秒). 执行号:1100.
SQL> select t1.
,t2.name from test1 t1,test2 t2 where t1.ID = t2.ID;

ID NAME NAME


3 小李 小王2
4 小刘 小张2

已用时间: 1.091(毫秒). 执行号:1101.
SQL> alter session 0 set events '10003 trace name context off';
操作已执行
已用时间: 0.439(毫秒). 执行号:1102.
SQL> select * from v$dm_ini where para_name = 'TRACE_PATH';

PARA_NAME PARA_VALUE MIN_VALUE MAX_VALUE DEFAULT_VALUE MPP_CHK SESS_VALUE FILE_VALUE DESCRIPTION PARA_TYPE


TRACE_PATH /dm8/dmdbms/data/DAMENG/trace NULL NULL NULL N /dm8/dmdbms/data/DAMENG/trace NULL System trace path name READ ONLY

已用时间: 2.785(毫秒). 执行号:1103.
SQL> exit
[dmdba@master bin]$ cd /dm8/dmdbms/data/DAMENG/trace
[dmdba@master trace]$ ls -lrt
total 4
-rw-r--r-- 1 dmdba dinstall 285 Nov 3 23:06 DMSERVER_1103_2306_122980896.trc
[dmdba@master trace]$
4)查看对应的trc文件

说明:10003事件其实并不能查看SQL语句的执行计划,但是他能抓取一段时间内的想要抓取的SQL语句类型,故此处也把10003事件记录在内。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服