dm8数据库not exists调优总结

一次在单位工作群里看到了这样一段对话,觉着可以学习一下,特作此记录。先上一个SQL:

SELECT DISTINCT C2.GT_PID AS MDCODE,

       '2022Y00121' AS DATATIME

  FROM N35R_YB21007 C1,TMP_GATHER_TABLE C2

 WHERE NOT EXISTS (SELECT 1

                     FROM N35R_YB21007 t3

                    WHERE t3.MDCODE=C2.GT_PID

                      AND t3.DATATIME=?

                      AND t3.MD_GCORGTYPE=?

                      AND t3 MD_CURRENCY=?

                      AND t3 MD_GCADJTYPE=? )

   AND C2.EXECUTION_ID=?

来看他的执行计划:

可以看到这里的驱动表走了一个inner join,然后cost很高,达到了1074。而一共得到的结果集的行数是556381行。整体走了一个哈希右半连接。

对于not exists的优化思路,一般我总结为两种(其中一种就是群里这个大神提到的)。一种为将not exists改为left join。保证驱动结果集相对较小,改写时需要注意在最后加上一个被驱动表连接列 is null的关键字。这用于保证结果集在改写SQL后的相等性。

这种改写方法可以就是解决当外部表过大,每次刷not exists的结果集时造成的sql执行损耗。但重点在于达梦数据库有一个SPL的扁平化特性。可以尝试在不修改SQL的前提下,让相关子查询结果集转变为一个固定的临时表结果集。而后和外表进行关联。保证了子查询不会一直因为外查询结果集过大而一直刷子查询结果集。相关参数为:enable_rq_to_nonref_spl

查询官方手册得到如下讲解:

相关查询表达式转化为非相关查询表达式,目的在于相关查询表达式的执行处理由之前的平坦化方式转化为一行一行处理,类似 ORACLE 的每行处理机制。

0:不启用该优化;

1:对查询项中出现的相关子查询表达式进行优化处理;

2:对查询项和 WHERE 表达式中出现的相关子查询表达式进行优化处理;

4:相关查询采用 SPL 方式去相关性后,可以作为单表过滤条件

支持使用上述有效值的组合值,如 3 表示同时进行 1 和 2 的优化

这里的非相关查询就是说,子查询的结果集不会因为父查询的原因而发生变化。这是可以理解的,因为子查询的结果集已经存在了临时表里,不会再更,即,不会多次刷表。

看群里大神将这个值增大到了7,即/*+ enable_rq_to_nonref_spl(7) */。用于查询上的优化。

最后总结下这篇文章究竟说了个啥:

  1. not exists的优化思路是啥(实际left join,方式可以加入并行,不做赘述)?
  2. 什么是相关子查询,什么是非相关子查询?
  3. enable_rq_to_nonref_spl参数(可写成hints)详解。

达梦数据库技术社区:https://eco.dameng.com 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在数据库中,`NOT EXISTS` 用于判断一个子查询的结果是否为空。如果结果为空,则返回 `TRUE`,否则返回 `FALSE`。 例如,如果你想查找所有不存在于表 `orders` 中的客户,你可以使用如下查询: ``` SELECT * FROM customers WHERE NOT EXISTS ( SELECT 1 FROM orders WHERE orders.customer_id = customers.id ) ``` 这个查询将返回所有在表 `customers` 中出现,但在表 `orders` 中没有出现过的客户。 总的来说,`NOT EXISTS` 用于判断一个子查询的结果是否为空,如果为空则返回 `TRUE`,否则返回 `FALSE`。 ### 回答2: 数据库中的Not Exists语句用于判断某个条件是否为假。具体而言,它用于检查在一个表中是否不存在与另一个表相关的记录。 Not Exists语句的基本语法是:SELECT column_name(s) FROM table_name WHERE NOT EXISTS (SELECT column_name(s) FROM table_name WHERE condition); 在执行过程中,数据库将先执行子查询(即括号内的语句),然后判断是否存在结果。如果子查询返回的结果为空集,即不存在满足条件的记录,则Not Exists语句返回真(True)。反之,如果子查询返回的结果不为空,即存在满足条件的记录,则Not Exists语句返回假(False)。 Not Exists语句在实践中应用广泛且有用。可以通过它来筛选出某个表中不在另一个表中的记录,以便进一步处理或进行其他操作。例如,可以使用Not Exists语句找出某学生没有选修过的课程,或查找某订单中未购买特定产品的客户。 需要注意的是,Not Exists语句的性能可能受到影响,尤其是在处理较大的数据集时。因此,在使用Not Exists语句时,需谨慎优化查询语句以提高性能,并确保所使用的关联条件正确无误。 总而言之,数据库中的Not Exists语句是用于判断某个条件是否为假的工具,通过检查一个表中是否不存在与另一个表相关的记录。它在数据库查询中有着广泛的应用,并可用于筛选、补全或其他操作。 ### 回答3: 数据库中的"NOT EXISTS"用于判断一个子查询是否为空。如果子查询为空,那么"NOT EXISTS"返回真;如果子查询不为空,那么"NOT EXISTS"返回假。 具体的工作原理如下: 1. 首先,数据库系统会执行子查询,获取其结果集。 2. 如果结果集为空,则"NOT EXISTS"返回真;如果结果集不为空,则"NOT EXISTS"返回假。 3. 在执行子查询过程中,如果发现一个匹配项,那么就会停止执行,并返回假。 4. 如果子查询执行完毕,没有找到匹配项,那么就会返回真。 通过使用"NOT EXISTS"语句,我们可以方便地判断一个表中是否存在符合某些条件的记录。 举个例子,假设我们有一个表格"Students",其中包含学生的学号和姓名。我们想要判断是否存在学号为"1001"的学生记录,我们可以使用以下SQL查询语句: SELECT * FROM Students WHERE NOT EXISTS (SELECT * FROM Students WHERE 学号 = '1001') 如果"Students"表中不存在学号为"1001"的学生记录,那么子查询将返回一个空的结果集,"NOT EXISTS"将返回真,即表示不存在符合条件的记录。相反,如果"Students"表中存在学号为"1001"的学生记录,那么子查询将返回一个非空的结果集,"NOT EXISTS"将返回假,即表示存在符合条件的记录。 总之,通过使用"NOT EXISTS"语句,我们可以进行方便的真假判断,从而进行数据库查询和操作的控制。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值