优化前:
简单来说,CONCATENATION中文的意思是级联,它和UNION/UNION ALL差不多,区别就是ORACLE在执行计划中跟据WHERE条件中的OR条件进行了拆分有两个或多个部分,然后进行去重处理,但是在这里只所以说和UNION/UNION ALL差不多,是因为CONCATENTION有去重功能,但不能完全消除重复值,它只是消除CONCATENATION中包含的两个子查询的重复值,看一个具体的案例
select a.*,b.dn
from temp_allcrmuser a, phs_smc_user b
where a.USERNUMBER = b.dn
and (a.ACTFLAG <> b.ACT_FLG or a.ENABLEFLAG <>b.ENABLE_FLG);
执行计划如下:
5 -filter("A"."ENABLEFLAG"<>"B"."ENABLE_FLG")
6 - access("A"."USERNUMBER"="B"."DN")
filter("A"."USERNUMBER"="B"."DN")
11 -filter("A"."ACTFLAG"<>"B"."ACT_FLG"ANDLNNVL("A"."ENABLEFLAG"<>"B"."ENABLE_FLG"))
12 - access("A"."USERNUMBER"="B"."DN")
filter("A"."USERNUMBER"="B"."DN")
优化后:
从执行计划中我们可以看出,ORACLE优化器对CONCATENATION跟据OR条件进行了拆分,对该类SQL我们怎么避免CONCATENATION操作呢?有两种优化方法,一种是改写SQL,别一种是添加hint
优化方法1,改写SQL
select *
from (selectrownum a_rownum,
a.ACTFLAG a_ACTFLAG,
a.ENABLEFLAGa_ENABLEFLAG,
b.dn,
b.ACT_FLG b_ACT_FLG,
b.ENABLE_FLGb_ENABLE_FLG
fromtemp_allcrmuser a
join phs_smc_user b
ona.USERNUMBER = b.dn) t
where (a_ACTFLAG <> b_ACT_FLG or a_ENABLEFLAG <>b_ENABLE_FLG);
执行计划如下:
优化方法2,使用hint
select
a.*, b.dn
from temp_allcrmuser a, phs_smc_user b
where a.USERNUMBER = b.dn
and (a.ACTFLAG <> b.ACT_FLG or a.ENABLEFLAG <>b.ENABLE_FLG);
执行计划如下:
扫描二维码关注我的微学堂
搜索刘老师微信号:Rman-2014,备注“Oracle学习与咨询”,即可添加好友;或者扫描下面二维码,关注我的“微学堂”公众号,了解最新OCP认证动态、题库及答案解析、培训机构及讲师介绍、课堂授课内容等。每天还有一篇技术文章发布哦!