in-list expansion也被称作or expansion

--针对in后面是常量集合的另外一种处理方法。优化器会把目标sql中in后面的常量集合拆开,把里面的每个常量都提出来形成一个分支,各分支之间用union all来连接。即in-list expansion本质是把带in的目标sql等价写成union all连接的各个分支。

in-list expansion改写成union all连接分支后,各个分支可以各自走索引、分区裁剪、表连接等相关的执行计划而不互相干扰;缺点是,改写后,随着union all分支的递加,sql解析时间对增多。

#先禁掉in-list iterator特性
SQL> alter session set events '10142 trace name context forever';
SQL> alter session set events '10157 trace name context forever';
SQL> exec dbms_stats.gather_table_stats(ownname=>'SCOTT',tabname=>'EMP1',cascade=>true,no_invalidate=>false);
SQL> select /*+ use_concat +*/ * from emp1 where deptno in (10,20,30);
SQL> select * from table(dbms_xplan.display_cursor(null,null,'advanced')); PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------
SQL_ID 2nk52krswqkxk, child number 0
-------------------------------------
select /*+ use_concat +*/ * from emp1 where deptno in (10,20,30) Plan hash value: 1141053746 ----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 6 (100)| |
| 1 | CONCATENATION | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| EMP1 | 3 | 114 | 2 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | IDX_EMP1_DEPT | 3 | | 1 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID| EMP1 | 5 | 190 | 2 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | IDX_EMP1_DEPT | 5 | | 1 (0)| 00:00:01 |
| 6 | TABLE ACCESS BY INDEX ROWID| EMP1 | 6 | 228 | 2 (0)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | IDX_EMP1_DEPT | 6 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------- Query Block Name / Object Alias (identified by operation id):
------------------------------------------------------------- 1 - SEL$1
2 - SEL$1_1 / EMP1@SEL$1
3 - SEL$1_1 / EMP1@SEL$1
4 - SEL$1_2 / EMP1@SEL$1_2
5 - SEL$1_2 / EMP1@SEL$1_2
6 - SEL$1_3 / EMP1@SEL$1_3
7 - SEL$1_3 / EMP1@SEL$1_3 ...... Predicate Information (identified by operation id):
--------------------------------------------------- 3 - access("DEPTNO"=10)
5 - access("DEPTNO"=20)
7 - access("DEPTNO"=30)

in-list expansion后,上面的语句其实被改写成下面的格式了:

select * from emp1 where deptno=10
union all
select * from emp1 where deptno=20
union all
select * from emp1 where deptno=30
union all;

要想优化器不走in-list expansion,需要使用no_expand hint

SQL> select /*+ no_expand +*/ * from emp1 where deptno in (10,20,30);
SQL> select * from table(dbms_xplan.display_cursor(null,null,'advanced')); PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------
SQL_ID akwm5wds8km03, child number 0
-------------------------------------
select /*+ no_expand +*/ * from emp1 where deptno in (10,20,30) Plan hash value: 2226897347 --------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 3 (100)| |
|* 1 | TABLE ACCESS FULL| EMP1 | 10 | 380 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------

  

对于in后面常量集合中所含元素数量非常多的情形(或or条件比较多的sql,OR关联词在CBO解析时,会变形(EXPAND)为UNION ALL的关联语句),可以考虑以下的优化方案:
1.使用no_expand hint不让cbo走in-list expansion类型的执行计划
2.将in后面的常量集合存储在一个中间表里,并将原始目标sql中的in改写成和这个表中间表做表连接

可以参考别人的优化示例:http://blog.itpub.net/26687597/viewspace-1207432/

in-list expansion的更多相关文章

  1. Protecting against XML Entity Expansion attacks

    https://blogs.msdn.microsoft.com/tomholl/2009/05/21/protecting-against-xml-entity-expansion-attacks/ ...

  2. BigDecimal除法运算出现java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result的解决办法

    BigDecimal除法运算出现java.lang.ArithmeticException: Non-terminating decimal expansion; no exact represent ...

  3. Project Euler 80:Square root digital expansion 平方根数字展开

    Square root digital expansion It is well known that if the square root of a natural number is not an ...

  4. poj 3168 Barn Expansion 几何yy

    题链:http://poj.org/problem? id=3168 Barn Expansion Time Limit: 1000MS   Memory Limit: 65536K Total Su ...

  5. poj3358 Period of an Infinite Binary Expansion

    Period of an Infinite Binary Expansion 题目大意:给你一个分数,求这个分数二进制表示下从第几位开始循环,并求出最小循环节长度. 注释:int范围内. 想法:这题说 ...

  6. expansion pattern ‘Frame&’ contains no argument packs

    camera/CameraImpl.h::: error: expansion pattern ‘Frame&’ contains no argument packs void read_fr ...

  7. UVA12627-Erratic Expansion(递归)

    Problem UVA12627-Erratic Expansion Accept: 465  Submit: 2487Time Limit: 3000 mSec Problem Descriptio ...

  8. 论文笔记系列-Multi-Fidelity Automatic Hyper-Parameter Tuning via Transfer Series Expansion

    论文: Multi-Fidelity Automatic Hyper-Parameter Tuning via Transfer Series Expansion 我们都知道实现AutoML的基本思路 ...

  9. Codeforces 799D Field expansion(随机算法)

    Field expansion [题目链接]Field expansion [题目类型]随机化算法 &题解: 参考自:http://www.cnblogs.com/Dragon-Light/p ...

随机推荐

  1. 这次,雅虎真的撤销QA团队了

    在一个软件开发过程中取消了质量保证团队会发生什么?更少,而不是更多的错误,以及一个大大加快的开发周期. 至少,根据雅虎的经验,确实如此.该公司的首席设计师Amotz Maimon,以及科学与技术高级副 ...

  2. Vijos1425子串清除 题解

    Vijos1425子串清除 题解   描述: 我们定义字符串A是字符串B的子串当且仅当我们能在B串中找到A串.现在给你一个字符串A,和另外一个字符串B,要你每次从B串中从左至右找第一个A串,并从B串中 ...

  3. asp.net mvc下的多语言方案 包含Html,Javascript和图片

    在网上查阅了众多方案,觉得路过秋天的方案 解耦性比较好,可以不使用微软的Resource文件,而是将所有的词汇放入在一个txt的词典之中,便于维护. 步骤如下: 1)在整个程序的入口处global.a ...

  4. 7zip ubuntu使用

    http://www.cnblogs.com/yiwd/p/3649094.html 安装: sudo apt-get install p7zip 解压: 7zr x file -r -o./path ...

  5. vim安装插件

    1. 下载bundle mkdir ~/.vim/bundlegit clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle 2 ...

  6. GO语言练习:值与引用

    1.代码 2.运行 package main import "fmt" func testValue(){ fmt.Println("for value") v ...

  7. Eclipse中添加PyDev插件

    思路 1.启动Eclipse, 2.点击Help->Install New Software... 3.在弹出的对话框中,点Add 按钮. 4.Name中填:Pydev, Location中填h ...

  8. java web(二) Tomcat数据源

    一.数据源的产生 1.JDBC操作原理 (1) 加载数据库驱动程序(数据库驱动程序可通过classpath配置): Class.forName(); (2)通过DriverManager类取得数据库连 ...

  9. odoo 动态创建字段的方法

    动态创建字段并非一个常见的的需求,但某些情况下,我们确实又需要动态地创建字段. Odoo 中创建字段的方法有两种,一种是通过python文件class中进行定义,另一种是在界面上手工创建,odoo通过 ...

  10. crontab的坑

    1. 命令  全路径 (eg:which mysql) 2.执行脚本  (脚本中加上#!/bin/bash) eg: /bin/bash script.sh 3. 输出信息(>>) 使用全 ...