首页 > 数据库 >达梦不支持filter类型的执行路径导致慢SQL

达梦不支持filter类型的执行路径导致慢SQL

时间:2024-03-08 09:16:08浏览次数:25  
标签:00 DGD filter 108 KEY SQL 00.01 ID 达梦

 

达梦不支持filter类型的执行路径导致慢SQL

 

最近有个政府项目的库往政务云上迁移到达梦库,源库的业务量不是很大,库本身也不大。

迁移后抓取达梦的AWR,发现有一条SQL每次执行需要15s多,而在原来的Oracle里边执行0.1s。

查看后发现是达梦不支持filter执行路径导致的。

模拟如下:

创建dgd,p,s共3个表。

create table dgd (hsstr varchar2(20),exstr varchar2(20));
create table p   (id number);
create table s   (id number,hs_str varchar2(40));

 

 

业务SQL如下:

select * from dgd
where exists (select 1
from p, s
where p.id = s.id
and dgd.hsstr || dgd.exstr like s.hs_str || '%');

 

SQL为半连接,关联条件使用了like,因此无论是在Oracle还是达梦都无法使用HASH JOIN算法。

SQL在Oracle和达梦的执行计划如下:

在Oracle和达梦里边,P和S表都使用了HASH JOIN算法。

由于Oracle的FILTER有去重效果,会减少ID为3,4,5的执行次数,

而在达梦里边,NEST LOOP SEMI JOIN2会导致ID为6,7,8的执行次数为DGD的结果集数,没有去重效果。

因此在驱动表关联字段重复数据多的情况下,因为无去重导致达梦实际上就慢很多了。

Oracle:
Plan hash value: 166352517

-----------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |      0 |00:00:00.01 |       3 |       |       |          |
|*  1 |  FILTER             |      |      1 |        |      0 |00:00:00.01 |       3 |       |       |          |
|   2 |   TABLE ACCESS FULL | DGD  |      1 |      1 |      0 |00:00:00.01 |       3 |       |       |          |
|*  3 |   HASH JOIN         |      |      0 |      1 |      0 |00:00:00.01 |       0 |  1393K|  1393K|          |
|   4 |    TABLE ACCESS FULL| P    |      0 |      1 |      0 |00:00:00.01 |       0 |       |       |          |
|*  5 |    TABLE ACCESS FULL| S    |      0 |      1 |      0 |00:00:00.01 |       0 |       |       |          |
-----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter( IS NOT NULL)
   3 - access("P"."ID"="S"."ID")
   5 - filter(:B1||:B2 LIKE "S"."HS_STR"||'%')


达梦:
1   #NSET2: [1, 1, 108] 
2     #PRJT2: [1, 1, 108]; exp_num(3), is_atom(FALSE) 
3       #NEST LOOP SEMI JOIN2: [1, 1, 108];  join condition(DGD.HSSTR || DGD.EXSTR LIKE S.HS_STR || '%')[with var]
4         #CSCN2: [1, 1, 108]; INDEX33557305(DGD)
5         #SLCT2: [1, 1, 108]; var4 LIKE S.HS_STR || '%'
6           #HASH2 INNER JOIN: [1, 1, 108];  KEY_NUM(1); KEY(P.ID=S.ID) KEY_NULL_EQU(0)
7             #CSCN2: [1, 1, 30]; INDEX33557306(P)
8             #CSCN2: [1, 1, 78]; INDEX33557308(S)

 

仔细看上边达梦的执行计划,[with var]表示使用了变量改写方式实现连接。

使用hint禁止变量改写之后,执行计划如下:

还是无法避免NEST LOOP。

1   #NSET2: [14, 1, 108] 
2     #PRJT2: [14, 1, 108]; exp_num(3), is_atom(FALSE) 
3       #NEST LOOP SEMI JOIN2: [14, 1, 108];  join condition(DGD.HSSTR || DGD.EXSTR LIKE S.HS_STR || '%')
4         #CSCN2: [1, 1, 108]; INDEX33557305(DGD)
5         #HASH2 INNER JOIN: [1, 1, 108];  KEY_NUM(1); KEY(P.ID=S.ID) KEY_NULL_EQU(0)
6           #CSCN2: [1, 1, 30]; INDEX33557306(P)
7           #CSCN2: [1, 1, 78]; INDEX33557308(S)

 

关于变量改写,资料太少。官网也搜不到详细的介绍信息。

只有相关hint的时候提到了一下:SQL调优连接方法hint

 

拓展

当半连接的关联条件为等价连接则可以使用HASH JOIN算法了。

但是需要各自添加hint。

Oracle                                                                                                                      达梦:
select * from dgd                                                                                                           explain select /*+ NO_USE_CVT_VAR OPTIMIZER_MODE(1) */ * from dgd
where exists (select /*+ unnest hash_sj */ 1                                                                                where exists (select  1
from p, s                                                                                                                   from p, s
where p.id = s.id                                                                                                           where p.id = s.id
and dgd.hsstr = s.hs_str );                                                                                                 and dgd.hsstr = s.hs_str );
                                                                                                                            
                                                                                                                            1   #NSET2: [1, 1, 108] 
Plan hash value: 1223244540                                                                                                 2     #PRJT2: [1, 1, 108]; exp_num(3), is_atom(FALSE) 
                                                                                                                            3       #HASH LEFT SEMI JOIN2: [1, 1, 108]; KEY_NUM(1);  KEY(DGD.HSSTR=DMTEMPVIEW_889204724.colname) KEY_NULL_EQU(0)
---------------------------------------------------------------------------------------------------------------------       4         #CSCN2: [1, 1, 108]; INDEX33557305(DGD)
| Id  | Operation            | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |       5         #PRJT2: [1, 1, 108]; exp_num(1), is_atom(FALSE) 
---------------------------------------------------------------------------------------------------------------------       6           #HASH2 INNER JOIN: [1, 1, 108];  KEY_NUM(1); KEY(P.ID=S.ID) KEY_NULL_EQU(0)
|   0 | SELECT STATEMENT     |         |      1 |        |      0 |00:00:00.01 |       1 |       |       |          |       7             #CSCN2: [1, 1, 30]; INDEX33557306(P)
|*  1 |  HASH JOIN SEMI      |         |      1 |      1 |      0 |00:00:00.01 |       1 |  1160K|  1160K|  451K (0)|       8             #CSCN2: [1, 1, 78]; INDEX33557308(S)
|   2 |   TABLE ACCESS FULL  | DGD     |      1 |      1 |      0 |00:00:00.01 |       1 |       |       |          |       
|   3 |   VIEW               | VW_SQ_1 |      0 |      1 |      0 |00:00:00.01 |       0 |       |       |          |       used time: 1.409(ms). Execute id is 0.
|*  4 |    HASH JOIN         |         |      0 |      1 |      0 |00:00:00.01 |       0 |  1393K|  1393K|          |
|   5 |     TABLE ACCESS FULL| P       |      0 |      1 |      0 |00:00:00.01 |       0 |       |       |          |
|   6 |     TABLE ACCESS FULL| S       |      0 |      1 |      0 |00:00:00.01 |       0 |       |       |          |
---------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("DGD"."HSSTR"="ITEM_1")
   4 - access("P"."ID"="S"."ID")

 

标签:00,DGD,filter,108,KEY,SQL,00.01,ID,达梦
From: https://www.cnblogs.com/PiscesCanon/p/18060233

相关文章

  • MYSQL学习笔记1: DDL的库表操作
    SQL语句分类DDL数据定义语言,用来定义数据库对象(数据库,表,字段)DML数据操作语言,用来对数据库中表的数据进行增删改DQL数据库查询语言,用于查询数据库中表的记录DCL数据控制语言,用来创建数据库用户、控制数据库的访问权限DDL数据定义语言,用来定义数据库对象(数据......
  • Docker搭建Mysql集群
    一、新建主服务器示例3307dockerrun-p3307:3306--namemysql-master\-v/docker-volume/mysql-master/log:/var/log/mysql\-v/docker-volume/mysql-master/data:/var/lib/mysql\-v/docker-volume/mysql-master/conf:/etc/mysql\-eMYSQL_ROOT_PASSWORD=root\-d......
  • MySQL-01.Linux下MySQL安装和使用
    C-01.Linux下MySQL的安装和使用前置说明,MySQL高级部分,需要前置知识,为Linux操作系统。如果没有该部分知识,这里推荐韩顺平老师的Linux操作系统的教程。韩老师Linux教程1.安装前准备1.1Linux系统及工具的准备安装并启动好两台虚拟机:CentOS7版本掌握克隆虚拟机的操作mac地......
  • MYSQL意向锁的作用
    结论:当一个事务要对表进行锁定时,首先会获取相应的意向锁。其他事务可以通过检查意向锁来判断是否有其他事务在更细粒度的级别上对表进行了锁定。这有助于避免冲突和提高并发性能在讨论此问题之前我们应当明确两个前提:Innodb存储引擎支持行锁和表锁共存行锁与表锁之间互不冲突......
  • MSSQL遇到以零作除数错误的处理方法
    https://www.cnblogs.com/huolarry/p/5766057.html在sql server中做除法处理的时候,我们经常需要处理除数为零的情况,因为如果遇到这种情况的时候,sqlserver会抛出遇到以零作除数错误的异常,我们总不希望把这个异常显示给用户吧。做个会报这个错误的示例,如以下sql代码:declare @a ......
  • Mybatis20_MyBatis映射文件深入(动态SQL)6
    一、动态sql语句1、动态sql语句概述Mybatis的映射文件中,前面我们的SQL都是比较简单的,有些时候业务逻辑复杂时,我们的SQL是动态变化的,此时在前面的学习中我们的SQL就不能满足要求了。2、环境搭建UserMapper.javapackagecom.itheima.mapper;importcom.......
  • SQL的知识补充
    case……when……selectsubstring(身份证号,7,8)as出生日期,YEAR(now())-YEAR(substring(身份证号,7,8))年龄,CASEwhenSubstring(身份证号,17,1)%2=1then'男'else'女'ENDAS性别from转换 case……when……子句主要用于多种情况的分类去......
  • MySQL8.0.21安装初始化失败
    情况说明:安装到最后一步第三个“Initializedatabase(maytakealongtime)”打叉,“Log”中存在“mysqld:File'.\鐜嬫旦鐒?bin.index'notfound(OSerrno2-Nosuchfileordirectory)”,已退出安装程序。问题分析:如果是第一次安装,问题在主机名称是中文;如果曾退出安装,问题......
  • mysql.h学习记录
    目录简介简介mysql.h是MySQLCAPI的主要头文件,它为C开发者提供了一套函数和定义,以与MySQL服务器交互。这些函数和定义使得开发者能够编写应用程序,实现与MySQL服务器的连接、执行查询、检索结果等操作。以下是一些常见的函数及其在mysql.h中的简要介绍:连接和关......
  • MySQL 的 datetime 日期类型,以当前时间作为初始默认值
     1.以当前时间作为默认值使用DEFAULTCURRENT_TIMESTAMP声明字段,插入记录时不用指定dt,自动置入当前时间CREATETABLEt1(dtDATETIMEDEFAULTCURRENT_TIMESTAMP); 2.以当前时间作为默认值以及更新值使用ONUPDATECURRENT_TIMESTAMP声明字段,修改记录时dt自......