查詢重寫是指當對物化視圖的基表進行查詢時,Oracle會自動判斷能否通過查詢物化視圖來得到結果,如果可以,則避免了聚集或連接操作,而直接從已經計算好的物化視圖中讀取數據。
1. 在scott下做測試,一個普通的2表關聯查詢
> alter system flush buffer_cache;
收集統計信息
> exec dbms_stats.gather_table_stats('SCOTT','EMP',cascade=>true);
> exec dbms_stats.gather_table_stats('SCOTT','DEPT',cascade=>true);
> set autotrace traceonly
> select ename,job,dname from emp,dept where emp.deptno=dept.deptno;
14 rows selected.
PLAN_TABLE_OUTPUT
Plan hash value: 844388907
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 420 | 6 (17)| 00:00:01 |
| 1 | MERGE JOIN | | 14 | 420 | 6 (17)| 00:00:01 |
| 2 | TABLE ACCESS BY INDEX ROWID | DEPT | 4 | 52 | 2 (0)| 00:00:01 |
| 3 | INDEX FULL SCAN | PK_DEPT | 4 | | 1 (0)| 00:00:01 |
|* 4 | SORT JOIN | | 14 | 238 | 4 (25)| 00:00:01 |
| 5 | TABLE ACCESS FU | EMP | 14 | 238 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
10 consistent gets
8 physical reads
0 redo size
970 bytes sent via SQL*Net to client
519 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
14 rows processed
以上,物理讀和一致性讀分別是8,10
2. 創建以上對象的物化視圖,並查看通過物化視圖查詢所得到的執行計划以及統計信息
CREATE MATERIALIZED VIEW LOG ON emp
WITH ROWID
INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW LOG ON dept
WITH ROWID
INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW emp_dept_mv_01
BUILD IMMEDIATE
REFRESH force ON COMMIT
as select ename,job,dname
from emp,dept
where emp.deptno=dept.deptno;
> alter system flush buffer_cache;
收集統計信息,可以針對物化視圖
> exec dbms_stats.gather_table_stats('SCOTT','EMP_DEPT_MV_01',cascade=>true);
> select * from emp_dept_mv_01;
Execution Plan
----------------------------------------------------------
Plan hash value: 2905768236
---------------------------------------------------------------------------------------
| Id | Operation
| Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT
| | 14 | 308 | 3 (0)| 00:00:01 |
| 1 | MAT_VIEW ACCESS FULL | EMP_DEPT_MV_01 | 14 | 308 | 3
(0)| 00:00:01 |
---------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
2 physical reads
0 redo size
1079 bytes sent via SQL*Net to client
519 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
14 rows processed
通過物化視圖的查詢,發現只有4個一致性讀和2個物理讀(相比先前的10,8),說明物化視圖會為系統帶來一定的性能提升
3. 將物化視圖設置為enable query rewrite(默認為disable),並執行原查詢語句,查看執行計划
> alter MATERIALIZED VIEW EMP_DEPT_MV_01 enable query rewrite;
> alter system flush buffer_cache;
> select ename,job,dname from emp,dept where emp.deptno=dept.deptno;
14 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 1320338361
-----------------------------------------------------------------------------------------------
| Id | Operation
| Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT
| | 14 | 308 | 3 (0)| 00:00:01 |
| 1 | MAT_VIEW REWRITE ACCESS FULL| EMP_DEPT_MV_01 | 14 | 308 | 3
(0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
3 consistent gets
2 physical reads
0 redo size
1079 bytes sent via SQL*Net to client
519 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
14 rows processed
該語句實際上自動查詢的是與其對應的物化視圖。
一致性讀/物理讀由原來的(10,8),下降到了(3,2),效果明顯.
總結:
特定場景中,利用物化視圖可提高查詢速度,但需要額外的存儲空間;
查詢重寫: 無需改變代碼,只需創建一個支持查詢重寫的物化視圖即可提高檢索性能