【sql調優之執行計劃】query transformer

yellowlee發表於2010-08-23

版本:10.2.0.4

解析後的查詢由多個查詢塊組成,這些查詢塊(query block)互相之間是巢狀或者關聯的關係,查詢結構確定這些查詢塊是如何互相關聯的,oracle的查詢轉換器(query transformer)的主要目的就是改變查詢的結構以獲得更佳的查詢計劃。有query transformer主要有四個不同的轉換技術:

View mergeing(檢視合併)

Predicate pushing(謂詞推進)

Subquery unnesting

Query rewrite with materialized views(物化檢視 查詢重寫)

 

View mergeing(檢視合併)

SQL> create view v_emp_query1 as

  2  select a.*,b.dname,b.loc from scott.emp a,scott.dept b

  3  where a.deptno = b.deptno

  4  and b.deptno = 20;

 

View created.

SQL>

SQL> select a.empno from v_emp_query1 a where a.empno > 1000;

 

 

Execution Plan

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

Plan hash value: 3850801593

 

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

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

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

|   0 | SELECT STATEMENT             |         |     5 |    50 |     2   (0)| 00:00:01 |

|   1 |  NESTED LOOPS                |         |     5 |    50 |     2   (0)| 00:00:01 |

|*  2 |   INDEX UNIQUE SCAN          | PK_DEPT |     1 |     3 |     0   (0)| 00:00:01 |

|*  3 |   TABLE ACCESS BY INDEX ROWID| EMP     |     5 |    35 |     2   (0)| 00:00:01 |

|*  4 |    INDEX RANGE SCAN          | PK_EMP  |    14 |       |     1   (0)| 00:00:01 |

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

 

Predicate Information (identified by operation id):

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

 

   2 - access("B"."DEPTNO"=20)

   3 - filter("A"."DEPTNO"=20)

   4 - access("A"."EMPNO">1000)

可以看到oracle進行了檢視合併,上面的查詢與下面的這個查詢等價:

SQL> select a.*,b.dname,b.loc from scott.emp a,scott.dept b

  2  where a.deptno = b.deptno

  3  and b.deptno = 20

  4  and a.empno > 1000;

 

 

Execution Plan

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

Plan hash value: 3440938035

 

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

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

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

|   0 | SELECT STATEMENT             |         |     5 |   290 |     3   (0)| 00:00:01 |

|   1 |  NESTED LOOPS                |         |     5 |   290 |     3   (0)| 00:00:01 |

|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    20 |     1   (0)| 00:00:01 |

|*  3 |    INDEX UNIQUE SCAN         | PK_DEPT |     1 |       |     0   (0)| 00:00:01 |

|*  4 |   TABLE ACCESS BY INDEX ROWID| EMP     |     5 |   190 |     2   (0)| 00:00:01 |

|*  5 |    INDEX RANGE SCAN          | PK_EMP  |    14 |       |     1   (0)| 00:00:01 |

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

 

Predicate Information (identified by operation id):

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

 

   3 - access("B"."DEPTNO"=20)

   4 - filter("A"."DEPTNO"=20)

   5 - access("A"."EMPNO">1000)

但也並不是所有的檢視都能合併,一些包含了集運算(union,union all,intersect,minus等),connect by,rownum偽列,聚合函式(avg,count,max,min,sum)等運算的查詢檢視並不能合併。一些group bydistinct操作只有在允許了複雜檢視合併時才有可能進行合併。

另外檢視合併可能會帶來安全性問題,有一個引數用來設定是否考慮檢視合併的安全性,optimizer_secure_view_merging,預設值是true

SQL> show parameters view

 

NAME                                 TYPE        VALUE

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

optimizer_secure_view_merging        boolean     TRUE

 

Predicate pushing(謂詞推進)

對於沒有合併的一些檢視,查詢轉換器可以將相關的謂詞加入到相應的查詢塊中,這種技術改進了未合併的檢視的子計劃,推進後的謂詞可以被用來訪問索引或者作為filters(過濾器)

 

Subquery unnesting

和檢視類似,一個子查詢也是有許多查詢塊組成。有時候一些巢狀的子查詢,可以轉換成join,從而產生較為優化的執行計劃。

 

Query  rewrite with materialized views使用物化檢視進行查詢重寫

如果查詢可以通過使用上已有的物化檢視而產生較優的計劃,那麼可能會發生這種情況。具體在分析物化檢視的時候詳述。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16179598/viewspace-671630/,如需轉載,請註明出處,否則將追究法律責任。

相關文章