谓词推入

--Join Predicate Pushdown
create table emp1 as select * from scott.emp

create table emp2 as select * from scott.emp

create index idx_emp1 on emp1(empno);

create index idx_emp2 on emp2(empno);

create or replace view emp_view as select
emp1.empno as empno1 from emp1
 
create or replace view emp_view_union as
select emp1.empno as empno1 from emp1 union all
select emp2.empno as empno2 from emp2

select /*+ no_merge(emp_view) */
 emp.empno
  from emp, emp_view
 where emp.empno = emp_view.empno1(+)
   and emp.ename = ‘FORD‘
   
   
 Plan Hash Value  : 101695337
------------------------------------------------------------------------------
| Id  | Operation                | Name     | Rows | Bytes | Cost | Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |          |    1 |    22 |    3 | 00:00:01 |
|   1 |   NESTED LOOPS OUTER     |          |    1 |    22 |    3 | 00:00:01 |
| * 2 |    TABLE ACCESS FULL     | EMP      |    1 |    20 |    2 | 00:00:01 |
|   3 |    VIEW PUSHED PREDICATE | EMP_VIEW |    1 |     2 |    1 | 00:00:01 |
| * 4 |     INDEX RANGE SCAN     | IDX_EMP1 |    1 |    13 |    1 | 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 2 - filter("EMP"."ENAME"=‘FORD‘)
* 4 - access("EMP1"."EMPNO"="EMP"."EMPNO") --谓词推入

select /*+ no_merge(emp_view) no_push_pred(emp_view) */ --禁止谓词推入,视图合并
 emp.empno
  from emp, emp_view
 where emp.empno = emp_view.empno1(+)
   and emp.ename = ‘FORD‘
   
 Plan Hash Value  : 1524044994

--------------------------------------------------------------------------
| Id  | Operation            | Name     | Rows | Bytes | Cost | Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |          |    1 |    33 |    3 | 00:00:01 |
| * 1 |   HASH JOIN OUTER    |          |    1 |    33 |    3 | 00:00:01 |
| * 2 |    TABLE ACCESS FULL | EMP      |    1 |    20 |    2 | 00:00:01 |
|   3 |    VIEW              | EMP_VIEW |   15 |   195 |    1 | 00:00:01 |
|   4 |     INDEX FULL SCAN  | IDX_EMP1 |   15 |   195 |    1 | 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 1 - access("EMP"."EMPNO"="EMP_VIEW"."EMPNO1"(+))
* 2 - filter("EMP"."ENAME"=‘FORD‘)

--视图中含有union all
select emp.empno
  from emp, emp_view_union
 where emp.empno = emp_view_union.empno1
   and emp.ename = ‘FORD‘
 Plan Hash Value  : 152695365
------------------------------------------------------------------------------------------
| Id  | Operation                      | Name           | Rows | Bytes | Cost | Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                |    2 |    66 |    4 | 00:00:01 |
|   1 |   NESTED LOOPS OUTER           |                |    2 |    66 |    4 | 00:00:01 |
| * 2 |    TABLE ACCESS FULL           | EMP            |    1 |    20 |    2 | 00:00:01 |
|   3 |    VIEW /*没有进行视图合并 *|  |MP_VIEW_UNION |    1 |    13 |    2 | 00:00:01 |
|   4 |     UNION ALL PUSHED PREDICATE |  /* 谓词推入*/              |      |       |      |          |
| * 5 |      INDEX RANGE SCAN          | IDX_EMP1       |    1 |    13 |    1 | 00:00:01 |
| * 6 |      INDEX RANGE SCAN          | IDX_EMP2       |    1 |    13 |    1 | 00:00:01 |
------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 2 - filter("EMP"."ENAME"=‘FORD‘)
* 5 - access("EMP1"."EMPNO"="EMP"."EMPNO")
* 6 - access("EMP2"."EMPNO"="EMP"."EMPNO")
Note
-----
- dynamic sampling used for this statement
--谓词推入条件;视图中含有union all,不能进行视图合并,视图基表的链接条件上已经有了索引*/

--如果禁止谓词推入,那么视图可能走出全表或者索引全扫描

select /*+ no_push_pred(emp_view_union) */
 emp.empno
  from emp, emp_view_union
 where emp.empno = emp_view_union.empno1
   and emp.ename = ‘FORD‘  
 Plan Hash Value  : 2461179762
--------------------------------------------------------------------------------
| Id  | Operation            | Name           | Rows | Bytes | Cost | Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                |    2 |    66 |    4 | 00:00:01 |
| * 1 |   HASH JOIN          |                |    2 |    66 |    4 | 00:00:01 |
| * 2 |    TABLE ACCESS FULL | EMP            |    1 |    20 |    2 | 00:00:01 |
|   3 |    VIEW              | EMP_VIEW_UNION |   30 |   390 |    2 | 00:00:01 |
|   4 |     UNION-ALL        |                |      |       |      |          |
|   5 |      INDEX FULL SCAN | IDX_EMP1       |   15 |   195 |    1 | 00:00:01 |
|   6 |      INDEX FULL SCAN | IDX_EMP2       |   15 |   195 |    1 | 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 1 - access("EMP"."EMPNO"="EMP_VIEW_UNION"."EMPNO1")
* 2 - filter("EMP"."ENAME"=‘FORD‘)
Note
-----
- dynamic sampling used for this statement

---CBO在做谓词推入的时候会考虑成本;如果谓词推入后成本大于之前的,那么不会进行谓词推入

select /*+ cardinality(emp 1000000) */
 emp.empno
  from emp, emp_view_union
 where emp.empno = emp_view_union.empno1
   and emp.ename = ‘FORD‘

Plan Hash Value  : 1728342133
------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name           | Rows    | Bytes    | Cost | Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                | 2000000 | 66000000 |   25 | 00:00:01 |
|   1 |   MERGE JOIN                   |                | 2000000 | 66000000 |   25 | 00:00:01 |
| * 2 |    TABLE ACCESS BY INDEX ROWID | EMP            | 1000000 | 20000000 |   10 | 00:00:01 |
|   3 |     INDEX FULL SCAN            | SYS_C0093796   |      15 |          |    2 | 00:00:01 |
| * 4 |    SORT JOIN                   |                |      30 |      390 |    3 | 00:00:01 |
|   5 |     VIEW                       | EMP_VIEW_UNION |      30 |      390 |    2 | 00:00:01 |
|   6 |      UNION-ALL                 |                |         |          |      |          |
|   7 |       INDEX FULL SCAN          | IDX_EMP1       |      15 |      195 |    1 | 00:00:01 |
|   8 |       INDEX FULL SCAN          | IDX_EMP2       |      15 |      195 |    1 | 00:00:01 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 2 - filter("EMP"."ENAME"=‘FORD‘)
* 4 - access("EMP"."EMPNO"="EMP_VIEW_UNION"."EMPNO1")
* 4 - filter("EMP"."EMPNO"="EMP_VIEW_UNION"."EMPNO1")

Note
-----
- dynamic sampling used for this statement

--如果此时强制谓词推入,按照oracle 成本估算大大增加
select /*+ cardinality(emp 1000000) push_pred(emp_view_union) */
 emp.empno
  from emp, emp_view_union
 where emp.empno = emp_view_union.empno1
   and emp.ename = ‘FORD‘
   
 Plan Hash Value  : 2223410919
---------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name           | Rows    | Bytes    | Cost    | Time     |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                | 1000000 | 33000000 | 2001778 | 06:40:22 |
|   1 |   NESTED LOOPS                 |                | 1000000 | 33000000 | 2001778 | 06:40:22 |
| * 2 |    TABLE ACCESS FULL           | EMP            | 1000000 | 20000000 |       2 | 00:00:01 |
|   3 |    VIEW                        | EMP_VIEW_UNION |       1 |       13 |       2 | 00:00:01 |
|   4 |     UNION ALL PUSHED PREDICATE |                |         |          |         |          |
| * 5 |      INDEX RANGE SCAN          | IDX_EMP1       |       1 |       13 |       1 | 00:00:01 |
| * 6 |      INDEX RANGE SCAN          | IDX_EMP2       |       1 |       13 |       1 | 00:00:01 |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 2 - filter("EMP"."ENAME"=‘FORD‘)
* 5 - access("EMP1"."EMPNO"="EMP"."EMPNO")
* 6 - access("EMP2"."EMPNO"="EMP"."EMPNO")
Note
-----
- dynamic sampling used for this statement

---内联视图,也会进行谓词推入的
select /*+ no_merge(emp_view_inline) */
 emp.empno
  from emp, (select emp1.empno as empno1 from emp1) emp_view_inline
 where emp.empno = emp_view_inline.empno1(+)
   and emp.ename = ‘FORD‘
 Plan Hash Value  : 3347874242
------------------------------------------------------------------------------
| Id  | Operation                | Name     | Rows | Bytes | Cost | Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |          |    1 |    22 |    3 | 00:00:01 |
|   1 |   NESTED LOOPS OUTER     |          |    1 |    22 |    3 | 00:00:01 |
| * 2 |    TABLE ACCESS FULL     | EMP      |    1 |    20 |    2 | 00:00:01 |
|   3 |    VIEW PUSHED PREDICATE |          |    1 |     2 |    1 | 00:00:01 |
| * 4 |     INDEX RANGE SCAN     | IDX_EMP1 |    1 |    13 |    1 | 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 2 - filter("EMP"."ENAME"=‘FORD‘)
* 4 - access("EMP1"."EMPNO"="EMP"."EMPNO")
Note
-----
- dynamic sampling used for this statement
/*   能否做谓词推入与目标视图是否能做视图合并,是否是内联视图没有关系
但是与目标视图的类型,与外部查询之间的链接类型以及链接方法有关系 仅包含以下几种
视图定义中含有union all,union, distinct,group by,和外部查询之间是外连接,
反连接,半连接*/

--以下就无法做谓词推入,即使加入HINT

select /*+ no_merge(emp_view) push_pred(emp_view) */
 emp.empno
  from emp, emp_view
 where emp.empno = emp_view.empno1
   and emp.ename = ‘FORD‘

时间: 2024-11-08 00:57:03

谓词推入的相关文章

Oracle查询转换之连接谓词推入

连接谓词推入(Join Predicate  Pushdown)是优化器处理带视图的目标SQL的一种优化手段,它是指虽然优化器会把该SQL中视图的定义SQL语句当作一个独立单元来单独执行,但此时优化器会把原本处于该视图外部查询中和该视图之间的连接条件推入到该视图的定义SQL语句内部,这样是为了能使用上该视图内部相关基表上的索引,进而能走出基于索引的嵌套循环连接. 连接谓词推入所带来的基于索引的嵌套循环连接并不一定能走出更高效的执行计划,因为当做了连接谓词推入后,原目标SQL中的视图就和外部查询产

MySQL sql 无法自动谓词推入

mysql 版本 5.6.16: 优化前: [email protected] jd_credit 03:41:23>SELECT aaa.POP_VENDER_ACC_ID as accId, sum(aaa.aa1) as TC ->   FROM (SELECT a.POP_VENDER_ACC_ID, ->                a.POP_VENDER_NAME, ->                a.license_no, ->             

善于相人却遭择婿铁律,屡屡把女儿推入火坑(其父必有其子是不对的,唐太宗都教子无方,更何况别人?)

张宏杰  国家人文历史 也许是上天注定,曾国藩家的女人们大都命运多舛.和自己的姐妹们一样,曾国藩的头四个女儿,婚姻生活都不顺遂,只有最小的女儿是一个例外. 吊诡的是,头四个女儿的夫家,都是曾国藩千挑万选亲自择定的. 曾国藩的女婿,有几个共同特点:都是曾国藩的湖南好友或同事的孩子:这些孩子他都亲自见过,可谓知根知底:这些女婿的父亲都品行高尚,才气不凡. 按道理,这样选出来的女婿,肯定差不到哪里去.但是世事就是如此奇怪,曾国藩的设想居然一一落空. 曾国藩的长女曾纪静,嫁的是曾国藩翰林院同事.好友袁芳

玩拍照?HTC是要将自己推入黑暗深渊

时也?命也?很多时候,一家企业的发展会呈现较大幅度的波动,或从低谷反弹至巅峰,或从天堂直坠地狱.更多的是时候,是一种宿命,注定着企业的结局.苹果向我们展示了童话里最美的结局,三星也阐述着麻雀变凤凰的传奇,而HTC,却用自己的轨迹讲述了什么叫不作就不会死的真谛. 在经历过辉煌之后,HTC近几年一直在泥潭中无法挣脱出来.即使拼命地做出挽救措施,却也只是让自己越陷越深.近日,HTC再度调整自己的方向,将拍照做为自己反攻的武器.但在飞速发展的移动互联网时代,过多向拍照领域倾斜,只会将HTC推向更加黑暗的

SQL 编码规范

1. 必须对表起别名,方便调查表用了哪些列 比如 select owner,object_id,name from a,b where a.id=b.id; 如果不对表取别名,我怎么知道你访问的列是哪个表的.如果SQL几百行,如果SQL表关联很多,去死吧. 2. 数据库对象 命名 表             前缀/后缀 T_XXX 视图         前缀/后缀  V_XXX 物化视图  前缀/后缀 MV_XXX 索引         IDX_列名 特殊表 数据仓库 事实表  _FACT 数据

查询转换

视图合并,视图合并是一种能将内嵌或存储式视图展开为能够独立分析或者与查询剩余部分合成总体执行计划的独立查询的转换,改写后的语句基本上不包含视图.视图合并常常发生在当外部查询块的谓语包括下列项的时候. 能够在另一个查询块的索引中使用的列 能够在另一个查询块的分区截断中使用的列 在一个联结视图中能够限制返回行数的条件 . select * from orders o,(select sales_rep_id from orders) o_view where o.sales_rep_id=o_vie

【重磅干货】看了此文,Oracle SQL优化文章不必再看!

听“俊”一席话,胜读十年书.看了这篇由DBA+社群联合发起人丁俊大师(网名:dingjun123)分享的SQL优化大作,其他Oracle SQL优化文章都不必再看了! 专家简介 丁俊 网名:dingjun123 DBA+社群联合发起人 性能优化专家,Oracle ACEA,ITPUB开发版资深版主.8年电信行业从业经验,在某大型电信系统提供商工作7年,任资深工程师,从事过系统开发与维护.业务架构和数据分析.系统优化等工作.擅长基于ORACLE的系统优化,精通SQL.PL/SQL.JAVA等.电子

Oracle Hint 学习之一

APPEDND hint :用于控制insert 语句是否能以直接路径插入的方式插入数据. CACHE hint:用于控制目标sql在执行时是否将全表扫描目标表的数据块放到buffer cache的LRU链表的热端. MONITER hint:用于控制被执行的目标sql是否被sql monitor监控 Gather_plan_statistics hint:用于在目标sql执行时收集一些额外的统计信息: SQL> select /*+ gather_plan_statistics */ t1.e

个推首席架构师Qcon分享 |微服务架构的那些事儿

微服务架构需要注意哪些问题? 微服务架构,首先考虑客户端与服务端之间的通信问题.有两种解决办法,一是客户端与多个服务端直接进行通信,但存在对外暴露接口细节.众多接口协议无法统一.客户端的代码复杂.服务端升级相对困难等问题.二是客户端访问统一的API网关,由API网关调用众多服务接口,易实现统一通信协议,降低客户端和服务端代码耦合,也可以达到统一的鉴权和流控,然而此方式存在延时增加的风险,可能使API网关成为系统发展的瓶颈. 微服务架构是分布式服务架构,如何进行服务的注册和发现也是需要解决的问题.