背景是在一台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 引发的性能问题的更多相关文章

  1. Mysql中where条件一个单引号引发的性能损耗

    日常写SQL中可能会有一些小细节忽略了导致整个sql的性能下降了好几倍甚至几十倍,几百倍.以下这个示例就是mysql语句中的一个单引号('')引发的性能耗损,我相信很多朋友都遇到过,甚至还在这样写. ...

  2. 调用.NET Serviced Component引发的性能问题及其解决

    在企业用户环境里,.NET Serviced Component使用广泛.它比较好的把传统COM+封装和.NET应用逻辑衔接了起来,在服务器端应用起到重要作用..NET Serviced Compon ...

  3. try catch引发的性能优化深度思考

    关键代码拆解成如下图所示(无关部分已省略): 起初我认为可能是这个 getRowDataItemNumberFormat 函数里面某些方法执行太慢,从 formatData.replace 到 une ...

  4. 记一个由MemCached引发的性能问题

    最近有个项目用loadrunner做了压力测试,发现并发量还不到200服务器就支撑不住了.boss那边紧急开会,说此项目最近3个月内将有100家中大型公司用于校园招聘工作,如果这个问题不解决公司有可能 ...

  5. linux 内核中一个全局变量引发的性能问题

    为了调试一个功能,在一个内核模块中,增加了一个全局变量,用来统计自有skb池的申请情况. 因为是临时增加,所以没有考虑性能,一开始只是一个fail的统计,数量不多,也不太考虑是否有计数丢失的情况,毕竟 ...

  6. 由一次自建库迁移到阿里云RDS引发的性能问题。

    刚入职一互联网公司,项目正好处于计划上线的时间,由于公司前不久已经购买了rds服务,领导决定尝试一番! 当然,新事物.云事物还是要谨慎的.安排我先把测试环境数据库迁移上去,这里吐槽一下,往rds迁移一 ...

  7. (转)Linux NUMA引发的性能问题

    最近某客户的核心业务系统又出了翻译缓慢的情况.该问题在6月份也出现过,当时进行了一次调整. 我们首先来看下故障时间段的awr报告: 单纯的从TOP 5 event,基本上是看不出任何东西的,可能有人会 ...

  8. 系统级性能分析工具perf的介绍与使用

    测试环境:Ubuntu16.04(在VMWare虚拟机使用perf top存在无法显示问题) Kernel:3.13.0-32 系统级性能优化通常包括两个阶段:性能剖析(performance pro ...

  9. 视图合并、hash join连接列数据分布不均匀引发的惨案

    表大小 SQL> select count(*) from agent.TB_AGENT_INFO; COUNT(*) ---------- 1751 SQL> select count( ...

随机推荐

  1. 对RecycleView的多种item布局的封装

    本文是借鉴bingoogolapple写得BGAAdapter-Android而产生的,对此表示感谢. 效果 1.Adapter的使用 1.继承BaseAdapter 这里是我的adapter pub ...

  2. 使用passenger在Centos7部署Puma+Nginx+Ruby on Rails

    安装ruby环境 RVM(ruby版本管理工具)安装 gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A170311 ...

  3. winform鼠标滚轮事件

    #region 进入窗体时加载 public FormAlarmInfoQuery() { InitializeComponent(); pictureBox1.ImageLocation = &qu ...

  4. Java 输入

    1.使用Scanner 使用时需要引入包import java.util.Scanner;首先定义Scanner对象 Scanner sc = new Scanner(System.in);如果要输入 ...

  5. .NET下的加密解密大全(3):非对称加密

    本博文列出了.NET下常用的非对称加密算法,并将它们制作成小DEMO,希望能对大家有所帮助. RSA[csharp]static string EnRSA(string data,string pub ...

  6. SQL生成一柱双色球

    数据库环境:SQL SERVER 2005 以前用C/JAVA穷举双色球的所有排列,今天想着换成用SQL实现,只生成一柱双色球. 简单说下双色球的规则,双色球由红色球和蓝色球组成,每注投注号码由6个红 ...

  7. XMPPFramework ios 例子中链接服务器失败,opnefire 服务器链接失败

    首先说下上周又做了几天得无用功, 之前一直用的是ejabberd ,这次换了opnefire,有人说opnefire跟新的xmpp协议不兼容,后来又更换成了ejabberd, Github 上得dem ...

  8. Graphics类绘制图形

    1. 画直线 void drawLine(int startX,int startY,int endX,int endY); 四个参数分别为:起始点的x坐标和y坐标以及终点的x坐标和y坐标,该方法用于 ...

  9. Java学习----不该初始化的class(抽象类)

    1. 抽象类声明有abstract 2.抽象类中有抽象方法,没有方法体的方法 // 抽象类 public abstract class Animal { public String name; pub ...

  10. spin.js插件的转圈加载效果

    先上插件链接地址:http://fgnass.github.io/spin.js/ 以下是使用spin.js插件的完整版测试例子: <!doctype html> <html> ...