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( ...
随机推荐
- Mybatis中实现oracle的批量插入、更新
oracle 实现在Mybatis中批量插入,下面测试可以使用,在批量插入中不能使用insert 标签,只能使用select标签进行批量插入,否则会提示错误 ### Cause: java.sql.S ...
- linux下的oracle数据库和表空间的导入导出
由于oracle是安装在linux上面,因此需要oracle的导入导出都是使用命令进行操作.oracle允许整个数据库导入导出和表空间的导入导出. 数据库导入导出 以下操作是在操作系统控制台命令中执行 ...
- centos 6.3 编译安装 nginx +mysql + php
这篇文章是对另一篇文章的整理,作为记录收藏 1,配置防火墙,开启80端口.3306端口 配置iptables,开启80端口.3306端口 vi /etc/sysconfig/iptables -A I ...
- Oracle创建存储过程、执行存储过程基本语法
>>>>>>>>>>>>>>>>>>>>>>>>> ...
- 29、Jquery Ajax
Ajax Asynchronsous Javascript and XML(异步Javascript和XML). Ajax 是一种无需重新加载整个页面的情况下,更新局部页面的技术. 不是指一种单一的技 ...
- portal开发"下拉框"“日期框”查询要怎么配置
下面的这些是我今天的成果! 总的来说是一步一步摸索出来的!还是等感谢超哥的耐心指导,犯了一些错误! 1.比如在wd配置文件中中写id=“check_it_two”,在java中写成 checki_it ...
- AcroExch.Rect 单位、属性问题
AcroExch.Rect 有四个属性:Top,Right,Left,Buttom 1.单位:point,一般通过英寸换算,1point=1/72 inch(英寸) 2.属性:Top: 区域距离 x ...
- iOS 使用GBK编码的hmacMD5算法
该方法是写在工具类中的,而不是写在NSString的类别中 方法的声明: /** * 使用hmac-md5加密 * * @param clearText 原文 * @param secret ...
- Swift 中的getting和setter的使用
以下简单的介绍Swift中的getting和setting的使用方法: Xcode version: 6.1 先附代码: class Test { var num1: Double = 0.0 ini ...
- 【实习记】2014-08-18使用curl排错http头的content-length
总结一,用curl排错Content-Length设置错误,误导了客户端. 访问/cgi-bin/txproj_list时,firebug显示总是不多不少15秒,调试其他问题时郁闷. fire ...