【SQL優化器查詢變換器】檢視合併(View Merging)

楊奇龍發表於2010-09-09

(基於成本的優化器元件)
 
查詢變換器
  被解析器解析過的查詢語句進入查詢變換器,表現出來的是一組查詢塊(query block),
這些查詢塊之間是相互關聯的或者是巢狀的,查詢的形式決定這些查詢塊相互之間如何被關聯。查詢變換器的主要目的就是決定改變查詢的形式是否有利於產生一個好的執行計劃。查詢變換器使用四種不同的查詢變換技術:
1- 檢視合併(View Merging)
2- 謂詞推進(Predicate Pushing)
3- 非巢狀子查詢(Subquery Unnesting)
4- 物化檢視的查詢重寫(Query Rewrite with Materialized Views)

最終應用於查詢的也可以是以上四種變換技術的任意組合。
 
檢視合併
  查詢中的每個檢視都會被解析器擴充套件到一個獨立的查詢塊中,這個查詢塊本質上是用來描述檢視定義的,是檢視的結果。優化器的一個任務就是去分析這個獨立檢視查詢塊(view query block)併產生一個檢視子計劃(subplan),然後優化器在產生整個查詢執行計劃的同時使用檢視子計劃來處理剩餘的查詢部分。由於檢視是被獨立在整個查詢之外被優化的,因此這種技術常常會導致一個不良執行計劃的產生。
    查詢變換器通過將檢視查詢塊合併到查詢塊中從而消除這種不良執行計劃。絕大多數型別的檢視是可以被合併的。在一個檢視被合併後,它原有的檢視查詢塊被包含到查詢塊中,也就是說檢視查詢塊不存在了,因此也不再需要產生一個子計劃。 
SQL> create view v_emp 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.

Elapsed: 00:00:00.13

SQL> set autot traceonly exp
SQL> set linesize 999
SQL> select a.empno from v_emp a where a.empno >1000;
Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 2122483104

----------------------------------------------------------------------------------------
| 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)

----可以看出上述計劃發生了檢視合併。關於檢視的執行計劃和下面的是等價的。
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;
Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 3257024035

----------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |     5 |   285 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                |         |     5 |   285 |     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 |   185 |     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)

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

相關文章