采用MERGE 语句的非关联形式提升性能

简介:       今天照例巡查垃圾sql时,发现一个跑了很长时间的sql,且其执行计划也非常的大,这个sql非常可疑,得排查排查:     第一步,照例查询内存中的执行计划: SELECT * FROM TABLE(DBMS_XPLAN.

 

    今天照例巡查垃圾sql时,发现一个跑了很长时间的sql,且其执行计划也非常的大,这个sql非常可疑,得排查排查:

 

 

第一步,照例查询内存中的执行计划:

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('17t226txddfy5',0,'advanced'));

 

可以看出执行计划的cost花费非常的大,且Predicate Information(即谓语)部分全是filter过滤的,怎么会没有access访问呢???????拿出其具体的sql语句:

 

MERGE INTO FLN_RCW_CM_ENGINE_BLACK_PURIFI BLACK_PURIFI

USING (SELECT *

FROM (SELECT T.*,

ROW_NUMBER() OVER(PARTITION BY CERTIFICATION_NO_18, INFO_CHARACTER, FILTER_CONFIG_ID ORDER BY CERTIFICATION_NO_18) NUM

FROM FLN_RCW_CM_T_ENGINE_BLACK T) T

WHERE NUM = 1) BLACK

ON (BLACK_PURIFI.CERTIFICATION_NO_18 = BLACK.CERTIFICATION_NO_18 AND BLACK_PURIFI.INFO_CHARACTER = BLACK.INFO_CHARACTER AND (BLACK.FILTER_CONFIG_ID IS NULL OR BLACK_PURIFI.FILTER_CONFIG_ID = BLACK.FILTER_CONFIG_ID) AND BLACK_PURIFI.DATE_DELETE IS NULL)

WHEN MATCHED THEN

UPDATE

SET BATCH_DATE = :B1,

FLAG_DELETE = 'N',

PURIFICATION_DATE = :B1

WHEN NOT MATCHED THEN

INSERT

VALUES

(:B1,

BLACK.CERTIFICATION_NO_18,

BLACK.FILTER_GRADE,

BLACK.FILTER_GRADE_CONTENT,

BLACK.INFO_CHARACTER,

BLACK.INFO_CHARACTER_CONTENT,

'Y',

TO_DATE(:B1,

'yyyy-mm-dd'),

'N',

NULL,

SYSDATE,

SYSDATE,

:B1,

BLACK.FILTER_CONFIG_ID)

;

 

我们看看其数据量吧,我之前提出过一个观念:任何离开数据量来谈sql优化都是没有意义的

select * from vw_table_lhr v where v.TABLE_NAME in ('FLN_RCW_CM_ENGINE_BLACK_PURIFI','FLN_RCW_CM_T_ENGINE_BLACK');

 

可以看出,统计信息是最近收集的,一张是小表,一张是大表,根据sql语句可以看出该sql是属于典型的用小表来更新大表,根据原来的执行计划看出走的是NL连接,且内表是全表扫描,这样的话内表大约要要访问94W+次,每次都对10G的大表来全表扫描的,大家知道,NL连接至少要保证内表的关联列有个索引,外表返回的结果集非常的小这个时候效率才非常的高,但是这里呢????神马都不满足,,,,,你还敢走NL??????脑残,,,,,所以这个执行计划很恐怖的,当然也是错误的执行计划,这里应该走hash连接,或者利用一下索引神马的,当然,这里如果只是单纯的update语句的话,我们可以采用快速游标更新法,效率是非常好的,但是这里同时涉及到updateinsert语句,根据经验这个应该修改为merge语句的非关联形式的表对表的更新,所以优化后的sql如下:

 

 

优化后的sql

MERGE INTO RISKREPT.FLN_RCW_CM_ENGINE_BLACK_PURIFI BLACK_PURIFI

USING (SELECT BLACK_PURIFI.ROWID ROWIDS,

BLACK.*

FROM (SELECT *

FROM (SELECT T.*,

ROW_NUMBER() OVER(PARTITION BY CERTIFICATION_NO_18, INFO_CHARACTER, FILTER_CONFIG_ID ORDER BY CERTIFICATION_NO_18) NUM

FROM FLN_RCW_CM_T_ENGINE_BLACK T) T

WHERE NUM = 1) BLACK,

RISKREPT.FLN_RCW_CM_ENGINE_BLACK_PURIFI BLACK_PURIFI

WHERE BLACK_PURIFI.CERTIFICATION_NO_18 = BLACK.CERTIFICATION_NO_18

AND BLACK_PURIFI.INFO_CHARACTER = BLACK.INFO_CHARACTER

AND (BLACK.FILTER_CONFIG_ID IS NULL OR

BLACK_PURIFI.FILTER_CONFIG_ID = BLACK.FILTER_CONFIG_ID)

AND BLACK_PURIFI.DATE_DELETE IS NULL) T

ON (BLACK_PURIFI.ROWID = T.ROWIDS)

WHEN MATCHED THEN

UPDATE

SET BATCH_DATE = :B1,

FLAG_DELETE = 'N',

PURIFICATION_DATE = :B1

WHEN NOT MATCHED THEN

INSERT

VALUES

(:B1,

T.CERTIFICATION_NO_18,

T.FILTER_GRADE,

T.FILTER_GRADE_CONTENT,

T.INFO_CHARACTER,

T.INFO_CHARACTER_CONTENT,

'Y',

TO_DATE(:B1,

'yyyy-mm-dd'),

'N',

NULL,

SYSDATE,

SYSDATE,

:B1,

T.FILTER_CONFIG_ID)

;

优化后的执行计划:

 

 

从执行计划来看,对这个sql的简单优化进行的差不多了。

 

注:这篇文章是几天前就写好的,但是博客审核有点问题,今天重新发布一下,就在发布之前我看了一下该语句仍然在跑,也就是已经运行了大概4天的时间还没有跑完,,,,,时间就这么过去了,,,,,,所以对系统垃圾sql语句的监控仍然是比较重要的。

    这篇博客的后传地址:http://blog.itpub.net/26736162/viewspace-1222417/


  1. 大家看博文的时候应该注意解决问题的整体思路,这个才是重点
  2. 有关连接方式的另一篇博文 http://blog.itpub.net/26736162/viewspace-1208814/


 

目录
相关文章
|
7月前
|
Python
使用`merge`函数将两个dataframe合并在一起,然后使用`query`函数根据指定的条件选取数据
在pandas中,可以使用`merge`函数将两个dataframe合并在一起,然后使用`query`函数根据指定的条件选取数据。
83 1
|
4月前
|
SQL 分布式计算 算法
当两个表进行Join操作时,如果它们的数据不符合MapJoin规范,您可以尝试以下优化方案
当两个表进行Join操作时,如果它们的数据不符合MapJoin规范,您可以尝试以下优化方案
44 4
|
SQL 数据库管理
【SQL开发实战技巧】系列(九):一个update误把其他列数据更新成空了?Merge改写update!给你五种删除重复数据的写法!
本篇文章讲解的主要内容是:***你有没有经历过一个update把其他列数据清空了、使用merge更新合并记录、删除违反参照完整性的记录、给你五种删除重复数据的写法*** 【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。
【SQL开发实战技巧】系列(九):一个update误把其他列数据更新成空了?Merge改写update!给你五种删除重复数据的写法!
|
存储 SQL 并行计算
使用 PolarDB 开源版 bloom filter index 实现任意字段组合条件过滤
PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力. 本文将介绍使用 PolarDB 开源版 bloom filter index 实现任意字段组合条件过滤
238 0
|
SQL 数据挖掘 数据库
DataFrame多表合并拼接函数concat、merge参数详解+代码操作展示
DataFrame多表合并拼接函数concat、merge参数详解+代码操作展示
644 0
DataFrame多表合并拼接函数concat、merge参数详解+代码操作展示
|
数据库
tp5.1关联预加载 -- 并再次解释模型的关联
tp5.1关联预加载 -- 并再次解释模型的关联
162 0
tp5.1关联预加载 -- 并再次解释模型的关联
|
SQL 缓存 算法
写出好的Join语句,前提你得懂这些
因为驱动结果集越大,意味着需要循环的次数越多,也就是说在被驱动结果集上面所 需要执行的查询检索次数会越多。比如,当两个表(表 A 和 表 B) Join 的时候,如果表 A 通过 WHERE 条件过滤后有 10 条记录,而表 B 有 20 条记录。如果我们选择表 A 作为驱动表,也就是被驱动表的结果集为 20,那么我们通过 Join 条件对被驱动表(表 B)的比较过滤就会有 10 次。反之,如果我们选择表 B 作为驱动表,则需要有 20 次对表 A 的比较过滤。小贴士1:驱动表的定义:当进行多表连接查询时,1.指定了联接条件时,满足查询条件的记录行数少的表为驱动表,2.未指定联接条件时,行数少
|
SQL 算法 关系型数据库
PostgreSQL 任意字段数组合 AND\OR 条件,指定返回结果条数,构造测试数据算法举例
标签 PostgreSQL , 构造测试数据 , 任意字段组合AND,OR查询 , 指定结果集大小 背景 在进行一些实际的POC测试时,需要根据业务提出的需求构造数据,比如按照任意字段数组合 AND\OR 条件,指定返回结果条数,构造测试数据。
1436 0