1. 程式人生 > >21 檢視合併(view merge) --優化主題系列

21 檢視合併(view merge) --優化主題系列

檢視合併(viewmerge)

SQL語句中有內聯檢視(in-lineview,內聯檢視就是在from後面有select子查詢)

或者SQL語句中有用 createview...建立的檢視,CBO會將內聯檢視/檢視給展開,進行等價的改寫,這個過程就叫做檢視合併。如果沒有發生檢視合併,在執行計劃中,我們可以看到VIEW關鍵字。

select * from (select ... from x) a,b where a.id=b.id;a就是內聯檢視

下面舉個例子(基於SYSOracle11gR2)

有下面的SQL,其實這個SQL來自於我同事,他請求我優化:

SELECT to_char(wmsys.wm_concat(a.TABLE_NAME))

  FROM user_tables a, dba_objects b

 WHERE a.TABLE_NAME = b.OBJECT_NAME

   AND b.OWNER = 'HBTELEPS'

   ANDB.OBJECT_TYPE = 'TABLE';


user_tables 是不是被展開了??被展開了就叫檢視合併

現在我們用HINTNO_MERGE 禁止USER_TABLES 進行檢視合併

SELECT /*+ no_merge(a) */ to_char(wmsys.wm_concat(a.TABLE_NAME))

  FROM user_tables a, dba_objects b

 WHERE a.TABLE_NAME = b.OBJECT_NAME

   AND b.OWNER = 'HBTELEPS'

   AND B.OBJECT_TYPE = 'TABLE';


conn scott/tiger

create or replace view emp1 as select ename,job,deptno from empwhere sal>(select avg(sal) from emp);

select ename,job,dname,loc from emp1,dept whereemp1.deptno=dept.deptno;


沒有VIEW關鍵字

並且檢視的名字也不見了就檢視合併了


create or replace view emp1 as select ename,job,deptno from empwhere sal>(select avg(sal) from emp);

select ename,job,dname,loc from emp1,dept whereemp1.deptno=dept.deptno;

select ename, job, dname, loc

  from (select ename, job, deptno

          from emp

         where sal >(select avg(sal) from emp)) emp1,

       dept

 where emp1.deptno = dept.deptno;

為什麼可以進行檢視合併??數學公式的等價轉換

我很反對用大量的VIEW用了VIEW會出現效能問題

為什麼 CBO要進行VIEWMERGE呢??

CBO認為把檢視展開了能更好的進一步優化

因為如果不進行檢視合併,那麼這個檢視就會當成一整塊,在SQL執行過程中,這個檢視就會被當成一個結果集,然後再去和別的表/結果集關聯。如果進行了檢視合併,那麼這個檢視就不會當成一整塊了,它會被拆散,分開的執行。CBO通常情況下認為檢視進行合併之後,效能較高,所以一般情況下都會發生檢視合併。但是並不是每次進行了檢視合併效能就高,所以我們在進行SQL優化的時候要特別留意檢視合併。

請特別注意:當子查詢/視圖裡面有

1.子查詢有ROWNUM

2.子查詢有CUBE,ROLLUP

3.子查詢有UNION, UNION ALL

4. START WITH ,CONNECT BY

優化器可能就不會發生subqueryunnesting/view merge

這個時候就要改寫SQL(比如把exists改寫為in,notexists 改寫為notin等等)