查詢轉換方式


查詢轉換方式有很多種:
1、視圖合併(view merge )      2、子查詢展開( subquery unnesting )        3、謂詞推入 (predicate pushdown )    


1、視圖合併:就是視圖的基表和外部表做連接
  創建一個視圖
create view v1 as
select * from emp where deptno = 10;

select *
  from v1, dept
 where v1.deptno = dept.deptno
   and v1.job = 'CLERK';

找到v1的基表emp,做了視圖合併.emp和dept返回的記錄很少,所以走嵌套循環和hash都很正常


不讓他進行視圖合併的方法:

《1》/*+ no_meger(view)*/ 
《2》查詢塊包含分析函數或聚合函數、集合運算(例如union、intersect、minus),
order by字句或者使用了rownum,視圖合併將會被禁止或者限制。

rownum也會阻止謂詞推入
2、(1)、走子查詢展開:就是where子句後邊有in,not in,exists,not exists,<,<=,>,>=等,CBO認爲對SQL進行等價改寫以後能夠更好的進行優化,等價改寫的過程就是子查詢展開

SQL> select ename from emp where deptno in (select deptno from dept where dname like 'S');

執行計劃
----------------------------------------------------------
Plan hash value: 330698451

--------------------------------------------------------------------------------
| Id  | Operation           | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |          |     5 |   110 |     5  (20)| 00:00:01 |
|*  1 |  HASH JOIN SEMI     |          |     5 |   110 |     5  (20)| 00:00:01 |
|   2 |   TABLE ACCESS FULL | EMP      |    14 |   126 |     2   (0)| 00:00:01 |
|   3 |   VIEW              | VW_NSO_1 |     1 |    13 |     2   (0)| 00:00:01 |
|*  4 |    TABLE ACCESS FULL| DEPT     |     1 |    12 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------


   1 - access("DEPTNO"="$nso_col_1")
   4 - filter("DNAME" LIKE 'S')


統計信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads
          0  redo size
        248  bytes sent via SQL*Net to client
        339  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed




(2)、加一個Hint禁止走子查詢展開,只要有filter exists一定沒有走子查詢展開,


filter是嵌套表有多少不重複數據就會返回多少條記錄。


SQL> select ename from emp where deptno in (select /*+ no_unnest*/ deptno from dept where dname like 'S');

執行計劃
----------------------------------------------------------
Plan hash value: 1499841400


---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     5 |    45 |     8   (0)| 00:00:01 |
|*  1 |  FILTER            |      |       |       |            |          |
|   2 |   TABLE ACCESS FULL| EMP  |    14 |   126 |     2   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| DEPT |     1 |    12 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------


   1 - filter( EXISTS (SELECT /*+ NO_UNNEST */ 0 FROM "DEPT" "DEPT"
              WHERE "DEPTNO"=:B1 AND "DNAME" LIKE 'S'))
   3 - filter("DEPTNO"=:B1 AND "DNAME" LIKE 'S')

統計信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
         16  consistent gets
          0  physical reads
          0  redo size
        248  bytes sent via SQL*Net to client
        339  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed


or是阻止進行子查詢展開的條件。

查詢名字帶S的用戶或者empno>5000的人

(1)、
SQL> select ename from emp where deptno in (select deptno from dept where dname like 'S') or empno >= 5000 ;


執行計劃
----------------------------------------------------------
Plan hash value: 1499841400

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    14 |   182 |     2   (0)| 00:00:01 |
|*  1 |  FILTER            |      |       |       |            |          |
|   2 |   TABLE ACCESS FULL| EMP  |    14 |   182 |     2   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| DEPT |     1 |    12 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------


   1 - filter("EMPNO">=5000 OR  EXISTS (SELECT 0 FROM "DEPT" "DEPT"
              WHERE "DEPTNO"=:B1 AND "DNAME" LIKE 'S'))
   3 - filter("DEPTNO"=:B1 AND "DNAME" LIKE 'S')




統計信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          5  consistent gets
          0  physical reads
          0  redo size
        511  bytes sent via SQL*Net to client
        350  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         15  rows processed

(2)、改寫後的SQL語句:


SQL> select ename from emp where deptno in (select deptno from dept where dname like 'S')
  2  union all
  3  select ename from emp where empno >= 5000 ;

ENAME
--------------------
SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
JAMES
FORD
MILLER
h

已選擇15行。

執行計劃
----------------------------------------------------------
Plan hash value: 527984613


---------------------------------------------------------------------------------
| Id  | Operation            | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |          |    19 |   250 |     7  (43)| 00:00:01 |
|   1 |  UNION-ALL           |          |       |       |            |          |
|*  2 |   HASH JOIN SEMI     |          |     5 |   110 |     5  (20)| 00:00:01 |
|   3 |    TABLE ACCESS FULL | EMP      |    14 |   126 |     2   (0)| 00:00:01 |
|   4 |    VIEW              | VW_NSO_1 |     1 |    13 |     2   (0)| 00:00:01 |
|*  5 |     TABLE ACCESS FULL| DEPT     |     1 |    12 |     2   (0)| 00:00:01 |
|*  6 |   TABLE ACCESS FULL  | EMP      |    14 |   140 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("DEPTNO"="$nso_col_1")
   5 - filter("DNAME" LIKE 'S')
   6 - filter("EMPNO">=5000)

統計信息
----------------------------------------------------------
         24  recursive calls
          0  db block gets
         14  consistent gets
          0  physical reads
          0  redo size
        511  bytes sent via SQL*Net to client
        350  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         15  rows processed

3、謂詞推進( predicate pushdown 
不讓他做視圖合併,加一個hint/*+ no_merge(v1) */ 
select /*+ no_merge(v1) */ *
  from v1, dept
 where v1.deptno = dept.deptno
   and v1.job = 'CLERK';


原本執行計劃應該是,先進行表連接,然後再篩選結果,但是,這裏*4將“DEPTNO"=10 AND "JOB"='CLERK'
這個條件推入到視圖裏,先進行過濾然後進行合併。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章