oracle 子查询解嵌套和谓词推入(sqlsubquery unnest and pre_push)

Subquery Unnesting  In subquery unnesting, the optimizer transforms a nested query

into an equivalent join statement, and then optimizes the join. This transformation

enables the optimizer to take advantage ofthe join optimizer technique. The optimizer

can perform thistransformation only if the resulting join statement is guaranteed to

return exactly the samerows as the origin al statement, and if subqueries do not

contain aggregatefunctions such as AVG .

If the optimizer cannot transform a complexst atement into a join statement, it selects

execution plans for the parent statementand the subquery as though they were

separate statements. The optimizer then ex ecutesthe subquery and uses the rows

returned to execute the parent query. Toimprove execution speed of the overall query

plan, the optimizer orders the subplansefficiently.

 

Predicate Pushing   In predicate pushing, the optimizer"pushes" the relevant predicates

from the containing query block into theview query block. For views that are not

merged, this technique improves the subplanof the unmerged view because the

database can use the pushed-in predicatesto access indexes or to use as filters.

 

hr@ORCL>

hr@ORCL> create table t1 as select *from dba_objects where object_id<3000;

 

Table created.

 

hr@ORCL> create table t2 as select *from dba_objects ;

 

Table created.

 

hr@ORCL> create index idx_id1_t2 ont2(object_id,owner);

 

Index created.

 

hr@ORCL> create index idx_id1_t1 ont1(object_id);

 

Index created.

hr@ORCL> analyze table t1 computestatistics for all indexed columns;

 

Table analyzed.

 

hr@ORCL> analyze table t2 computestatistics for all indexed columns;

 

Table analyzed.

 

hr@ORCL> set autot traceonly

 

 

 

 

hr@ORCL> select object_id from t1 whereexists(

 2  select 1 from t2 wheret1.object_id=t2.object_id-10);

 

2874 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 2210107937

 

------------------------------------------------------------------------------------

| Id | Operation             |Name       | Rows  | Bytes | Cost (%CPU)| Time    |

------------------------------------------------------------------------------------

|   0| SELECT STATEMENT      |            |     1 |   17 |   294   (1)| 00:00:04 |

|*  1|  HASH JOIN SEMI       |            |     1 |   17 |   294   (1)| 00:00:04 |

|   2|   INDEX FAST FULL SCAN| IDX_ID1_T1|  2931 | 38103 |     5  (0)| 00:00:01 |

|   3 |  TABLE ACCESS FULL   | T2         | 62741 |   245K|  289   (1)| 00:00:04 |

------------------------------------------------------------------------------------

 

Predicate Information (identified byoperation id):

---------------------------------------------------

 

   1-access("T1"."OBJECT_ID"="T2"."OBJECT_ID"-10)

 

Note

-----

   -dynamic sampling used for this statement (level=2)

 

 

Statistics

----------------------------------------------------------

        32  recursive calls

         0  db block gets

      1345  consistent gets

         7  physical reads

         0  redo size

     50399  bytes sent via SQL*Net toclient

      2620  bytes received via SQL*Netfrom client

       193  SQL*Net roundtrips to/fromclient

         0  sorts (memory)

         0  sorts (disk)

      2874  rows processed

 

上面的例子中,oracle自动将子查询进行了展开,下面我们使用no_unnest hint来不让oracle在这里进行子查询展开,就通过
嵌套在子查询里面,那么这样比如就会走fiter了,如下:

hr@ORCL> alter system flush shared_pool;

 

System altered.

 

hr@ORCL> select object_id

 2  from t1

 3  where exists (select /*+no_unnest */

 4  1

 5  from t2

 6  wheret1.object_id=t2.object_id-10);

 

2874 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 895956251

 

---------------------------------------------------------------------------

| Id | Operation          | Name |Rows  | Bytes | Cost (%CPU)| Time     |

---------------------------------------------------------------------------

|   0| SELECT STATEMENT   |      |    1 |     3 |  4414  (1)| 00:00:53 |

|*  1|  FILTER            |      |      |       |            |          |

|   2|   TABLE ACCESS FULL| T1   | 2931 |  8793 |    13  (0)| 00:00:01 |

|*  3|   TABLE ACCESS FULL| T2   |  627 |  2508 |     3   (0)| 00:00:01 |

---------------------------------------------------------------------------

 

Predicate Information (identified byoperation id):

---------------------------------------------------

 

   1- filter( EXISTS (SELECT /*+ NO_UNNEST */ 0 FROM "T2" "T2"WHERE

             "T2"."OBJECT_ID"-10=:B1))

   3- filter("T2"."OBJECT_ID"-10=:B1)

 

Note

-----

   -dynamic sampling used for this statement (level=2)

 

 

Statistics

----------------------------------------------------------

       735  recursive calls

         0  db block gets

    123829  consistent gets

      1090  physical reads

         0  redo size

     50399  bytes sent via SQL*Net toclient

      2620  bytes received via SQL*Netfrom client

       193  SQL*Net roundtrips to/fromclient

        20  sorts (memory)

         0  sorts (disk)

      2874  rows processed

 

那么什么情况下存在子查询的情况,oracle不会进行子查询的展开呢 

 

l   包含rownum

hr@ORCL> select object_id

  2  fromt1

  3 where exists

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值