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

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]$
    查看对应的trc文件
 
说明:10003事件其实并不能查看SQL语句的执行计划,但是他能抓取一段时间内的想要抓取的SQL语句类型,故此处也把10003事件记录在内。

如需了解更多信息,请查看达梦技术社区:

达梦数据库 - 新一代大型通用关系型数据库 | 达梦在线服务平台达梦数据库产品体验站,DM8在线试玩,达梦数据库全系列产品免费下载,官方权威的快速上手文档和产品手册,最活跃的达梦技术社区,面向全行业ISV厂商免费的云适配服务。icon-default.png?t=N7T8https://eco.dameng.com/

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值