CONCATENATION 引发的性能问题
背景是在一台11gR2的机器上,开发反映一个批处理比以前慢了3倍。经过仔细查看该SQL的执行计划,发现由于SQL中使用了or,导致CBO走出了一个非常糟糕的CONCATENATION路径。
no_expand提示的说明是 The NO_EXPAND hint prevents the cost-based optimizer from considering OR-expansion for queries having OR conditions or IN-lists in the WHERE clause. Usually, the optimizer considers using OR expansion and uses this method if it decides that the cost is lower than not using it. use_concat提示的说明是 The USE_CONCAT hint forces combined OR conditions in the WHERE clause of a query to be transformed into a compound query using the UNION ALL set operator. Generally, this transformation occurs only if the cost of the query using the concatenations is cheaper than the cost without them. 为了重现这个问题,必须使用/*+ use_concat */来模拟。 explain plan for SELECT /*+ use_concat */
20130620,
B.mgr_code ,
B.mgr_name ,
B.cur_name ,
'3.4.2' ,
nvl(sum(ADJUST_AMT_AF),0) as acct_bal ,
nvl(sum(D_CMP_BAL),0) ,
nvl(sum(M_CMP_BAL),0) ,
nvl(sum(Y_CMP_BAL),0) ,
nvl(sum(Y_avg_af),0) as Y_avg_bal,
B.cur_code,
B.unit1_code,
B.unit2_code,
B.unit3_code,
B.dept1_code,
A.idx_name
FROM S_PM_IDX_CODE A,T_PM_ACCT_DTL_AF B
where B.ACCT_FLAG in('OPEN','LOAN')
AND A.ROWID='AABK8vAAyAAGg/2AAs'
AND SUBSTR(B.FLAG,1,1) IN ('3')
AND SUBSTR(B.FLAG,2,1) IN ('2')
AND SUBSTR(B.FLAG,3,1) IN ('2')
AND 1=1
AND 1=1
AND 1=1
AND 1=1
AND 1=1
AND 1=1
AND 1=1
and ((A.term_flag is null)
or (A.term_flag is not null and A.begin_term<B.term
and A.end_term >= B.term and B.term_flag = A.term_flag))
AND B.data_date = 20130620
group by B.mgr_code, B.mgr_name,
B.cur_code, B.cur_name,
B.unit1_code,B.unit2_code,
B.unit3_code,
B.dept1_code,
A.IDX_NAME; Plan hash value: 542663423 ------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 240 | 47236 (1)| 00:09:27 | | |
| 1 | HASH GROUP BY | | 1 | 240 | | | | |
| 2 | CONCATENATION | | | | | | | |
| 3 | NESTED LOOPS | | 1 | 240 | 23609 (1)| 00:04:44 | | |
|* 4 | TABLE ACCESS BY USER ROWID| S_PM_IDX_CODE | 1 | 97 | 1 (0)| 00:00:01 | | |
| 5 | PARTITION LIST SINGLE | | 1 | 143 | 23608 (1)| 00:04:44 | KEY | KEY |
|* 6 | TABLE ACCESS FULL | T_PM_ACCT_DTL_AF | 1 | 143 | 23608 (1)| 00:04:44 | 549 | 549 |
| 7 | NESTED LOOPS | | 1 | 240 | 23625 (1)| 00:04:44 | | |
|* 8 | TABLE ACCESS BY USER ROWID| S_PM_IDX_CODE | 1 | 97 | 1 (0)| 00:00:01 | | |
| 9 | PARTITION LIST SINGLE | | 1 | 143 | 23624 (1)| 00:04:44 | KEY | KEY |
|* 10 | TABLE ACCESS FULL | T_PM_ACCT_DTL_AF | 1 | 143 | 23624 (1)| 00:04:44 | 549 | 549 |
------------------------------------------------------------------------------------------------------------------ Predicate Information (identified by operation id):
--------------------------------------------------- 4 - filter("A"."TERM_FLAG" IS NOT NULL)
6 - filter("A"."BEGIN_TERM"<"B"."TERM" AND "A"."END_TERM">="B"."TERM" AND
"B"."TERM_FLAG"="A"."TERM_FLAG" AND ("B"."ACCT_FLAG"='LOAN' OR "B"."ACCT_FLAG"='OPEN') AND
SUBSTR("B"."FLAG",2,1)='2' AND SUBSTR("B"."FLAG",3,1)='2' AND SUBSTR("B"."FLAG",1,1)='3' AND
"B"."DATA_DATE"=20130620)
8 - filter("A"."TERM_FLAG" IS NULL)
10 - filter(("B"."ACCT_FLAG"='LOAN' OR "B"."ACCT_FLAG"='OPEN') AND SUBSTR("B"."FLAG",2,1)='2' AND
SUBSTR("B"."FLAG",3,1)='2' AND SUBSTR("B"."FLAG",1,1)='3' AND "B"."DATA_DATE"=20130620 AND
(LNNVL("B"."TERM_FLAG"="A"."TERM_FLAG") OR LNNVL("A"."BEGIN_TERM"<"B"."TERM") OR
LNNVL("A"."END_TERM">="B"."TERM") OR LNNVL("A"."TERM_FLAG" IS NOT NULL))) Note
-----
- dynamic sampling used for this statement (level=2) explain plan for
SELECT
20130620,
B.mgr_code ,
B.mgr_name ,
B.cur_name ,
'3.4.2' ,
nvl(sum(ADJUST_AMT_AF),0) as acct_bal ,
nvl(sum(D_CMP_BAL),0) ,
nvl(sum(M_CMP_BAL),0) ,
nvl(sum(Y_CMP_BAL),0) ,
nvl(sum(Y_avg_af),0) as Y_avg_bal,
B.cur_code,
B.unit1_code,
B.unit2_code,
B.unit3_code,
B.dept1_code,
A.idx_name
FROM S_PM_IDX_CODE A,T_PM_ACCT_DTL_AF B
where B.ACCT_FLAG in('OPEN','LOAN')
AND A.ROWID='AABK8vAAyAAGg/2AAs'
AND SUBSTR(B.FLAG,1,1) IN ('3')
AND SUBSTR(B.FLAG,2,1) IN ('2')
AND SUBSTR(B.FLAG,3,1) IN ('2')
AND 1=1
AND 1=1
AND 1=1
AND 1=1
AND 1=1
AND 1=1
AND 1=1
and ((A.term_flag is null)
or (A.term_flag is not null and A.begin_term<B.term
and A.end_term >= B.term and B.term_flag = A.term_flag))
AND B.data_date = 20130620
group by B.mgr_code, B.mgr_name,
B.cur_code, B.cur_name,
B.unit1_code,B.unit2_code,
B.unit3_code,
B.dept1_code,
A.IDX_NAME;
select * from table(dbms_xplan.display());
Plan hash value: 2396922436 ------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 240 | 8058 (1)| 00:01:37 | | |
| 1 | HASH GROUP BY | | 1 | 240 | 8058 (1)| 00:01:37 | | |
| 2 | NESTED LOOPS | | 1 | 240 | 8057 (1)| 00:01:37 | | |
| 3 | TABLE ACCESS BY USER ROWID | S_PM_IDX_CODE | 1 | 97 | 1 (0)| 00:00:01 | | |
| 4 | PARTITION LIST SINGLE | | 1 | 143 | 8056 (1)| 00:01:37 | KEY | KEY |
|* 5 | TABLE ACCESS BY LOCAL INDEX ROWID| T_PM_ACCT_DTL_AF | 1 | 143 | 8056 (1)| 00:01:37 | 549 | 549 |
|* 6 | INDEX RANGE SCAN | T_PM_ACCT_DTL_AF_IDX1 | 35022 | | 136 (1)| 00:00:02 | 549 | 549 |
------------------------------------------------------------------------------------------------------------------------------ Predicate Information (identified by operation id):
--------------------------------------------------- 5 - filter(("B"."ACCT_FLAG"='LOAN' OR "B"."ACCT_FLAG"='OPEN') AND SUBSTR("B"."FLAG",2,1)='2' AND
SUBSTR("B"."FLAG",3,1)='2' AND ("A"."TERM_FLAG" IS NULL OR "B"."TERM_FLAG"="A"."TERM_FLAG" AND
"A"."BEGIN_TERM"<"B"."TERM" AND "A"."END_TERM">="B"."TERM" AND "A"."TERM_FLAG" IS NOT NULL))
6 - access(SUBSTR("FLAG",1,1)='3') Note
-----
- dynamic sampling used for this statement (level=2)
CONCATENATION 引发的性能问题的更多相关文章
- Mysql中where条件一个单引号引发的性能损耗
日常写SQL中可能会有一些小细节忽略了导致整个sql的性能下降了好几倍甚至几十倍,几百倍.以下这个示例就是mysql语句中的一个单引号('')引发的性能耗损,我相信很多朋友都遇到过,甚至还在这样写. ...
- 调用.NET Serviced Component引发的性能问题及其解决
在企业用户环境里,.NET Serviced Component使用广泛.它比较好的把传统COM+封装和.NET应用逻辑衔接了起来,在服务器端应用起到重要作用..NET Serviced Compon ...
- try catch引发的性能优化深度思考
关键代码拆解成如下图所示(无关部分已省略): 起初我认为可能是这个 getRowDataItemNumberFormat 函数里面某些方法执行太慢,从 formatData.replace 到 une ...
- 记一个由MemCached引发的性能问题
最近有个项目用loadrunner做了压力测试,发现并发量还不到200服务器就支撑不住了.boss那边紧急开会,说此项目最近3个月内将有100家中大型公司用于校园招聘工作,如果这个问题不解决公司有可能 ...
- linux 内核中一个全局变量引发的性能问题
为了调试一个功能,在一个内核模块中,增加了一个全局变量,用来统计自有skb池的申请情况. 因为是临时增加,所以没有考虑性能,一开始只是一个fail的统计,数量不多,也不太考虑是否有计数丢失的情况,毕竟 ...
- 由一次自建库迁移到阿里云RDS引发的性能问题。
刚入职一互联网公司,项目正好处于计划上线的时间,由于公司前不久已经购买了rds服务,领导决定尝试一番! 当然,新事物.云事物还是要谨慎的.安排我先把测试环境数据库迁移上去,这里吐槽一下,往rds迁移一 ...
- (转)Linux NUMA引发的性能问题
最近某客户的核心业务系统又出了翻译缓慢的情况.该问题在6月份也出现过,当时进行了一次调整. 我们首先来看下故障时间段的awr报告: 单纯的从TOP 5 event,基本上是看不出任何东西的,可能有人会 ...
- 系统级性能分析工具perf的介绍与使用
测试环境:Ubuntu16.04(在VMWare虚拟机使用perf top存在无法显示问题) Kernel:3.13.0-32 系统级性能优化通常包括两个阶段:性能剖析(performance pro ...
- 视图合并、hash join连接列数据分布不均匀引发的惨案
表大小 SQL> select count(*) from agent.TB_AGENT_INFO; COUNT(*) ---------- 1751 SQL> select count( ...
随机推荐
- dbartisan下载地址
http://downloads.embarcadero.com/free/dbartisan
- 29、Jquery Ajax
Ajax Asynchronsous Javascript and XML(异步Javascript和XML). Ajax 是一种无需重新加载整个页面的情况下,更新局部页面的技术. 不是指一种单一的技 ...
- C#基础加强
1.代码规范 -命名规范:定义的变量或者方法名要有意义. 1.骆驼命名 :第一个单词首字母小写,之后的单词首字母大写 userName.userPassword.realName…(普通变量(局部变量 ...
- P2P之UDP穿透NAT原理
首先先介绍一些基本概念: NAT(Network Address Translators),网络地址转换:网络地址转换是在IP地址日益缺乏的情况下产生的,它的主要目的就 ...
- 如何在Sql2008中获取表字段属性和注释?
如何在Sql2008中获取表字段属性和注释? select b.[value] from sys.columns a left join sys.extended_properties b on a. ...
- hibernate - Transaction not successfully started
今天在测试 transaction(使用事务进行管理)的时候, 总报错: Transaction not successfully started 可能有多种原因, 这位哥们总结得很好: Transa ...
- AIX filesystemcache引发的Oracle事故
链接地址: http://www.jydba.net/aix-filesystemcache%e5%bc%95%e5%8f%91%e7%9a%84oracle%e4%ba%8b%e6%95%85/ A ...
- objective-c中字符串长度计算
我们知道,在c语言中,使用sizeof ()计算在内存中占用的字节数, 引用string.h后,使用strlen()计算字符串的长度(不包含\0). 而在object-c中, "length ...
- Membership角色与权限管理
安全性:成员资格与角色:验证与授权. 一.建数据库:在VS工具中用DOS环境执行ASPNET_REGSQL 二.配置程序访问数据库: > 在web.config之中加入 <connecti ...
- Windows phone 之Socket
服务器端: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sy ...