Oracle的實體化視圖(MVIEW)的深入研究之一
Oracle的實體化視圖(MVIEW)的深入研究之一
轉: AnySQL.net
從Oracle 8i開始提供了實體化視圖, 能過預先計算好的中間表來提高應用的訪問速度, 在特定的情況下是很有用的一項技術. 另外實體化視圖還可用於資料複製, 在這個上面的應用越來越多. MVIEW中經常跗以遇到重新整理很慢的情況, 如何提高呢? 首先來研究一下重新整理的過程. 下面是用來建立示範表的角本:
CREATE TABLE T_MVLOG (COL1 VARCHAR2(20));
CREATE MATERIALIZED VIEW LOG ON T_MVLOG
WITH ROWID, sequence;
CREATE MATERIALIZED VIEW MV_T_MVLOG
REFRESH FAST
WITH ROWID
AS
SELECT ROWID R_ID, A.* FROM T_MVLOG A;
我們對DBMS_MVIEW.REFRESH作一個SQL_TRACE, 在這個例子中, 我在基表中插入了一打記錄, 然後作跟蹤的. 可以看到第一步為:
update "ANYSQL"."MLOG$_T_MVLOG" set snaptime$$ = :1
where snaptime$$ >
to_date('2100-01-01:00:00:00','YYYY-MM-DD:HH24:MI:SS')
第二步, 取得在這段時間內發生修改的每一行的ROWID
SELECT DISTINCT M_ROW$$ FROM
(
SELECT M_ROW$$
FROM "ANYSQL"."MLOG$_T_MVLOG" MLOG$
WHERE "SNAPTIME$$" > :1 AND ("DMLTYPE$$" != 'I')
) LOG$
WHERE (M_ROW$$) NOT IN
(
SELECT ROWID FROM "T_MVLOG" "MAS_TAB$"
WHERE MAS_TAB$.ROWID = LOG$.M_ROW$$
)
第三步, 取得重新整理後的值
SELECT CURRENT$."R_ID",
CURRENT$."COL1",
ROWIDTOCHAR(CURRENT$.ROWID) M_ROW$$
FROM
(
SELECT "A".ROWID "R_ID","A"."COL1" "COL1" FROM "T_MVLOG" "A"
) CURRENT$,
(
SELECT DISTINCT M_ROW$$ FROM "ANYSQL"."MLOG$_T_MVLOG" MLOG$
WHERE "SNAPTIME$$" > :1 AND ("DMLTYPE$$" != 'D')
) LOG$
WHERE CURRENT$.ROWID = LOG$.M_ROW$$
第四步, 對MVIEW進行插入
INSERT INTO "ANYSQL"."MV_T_MVLOG" ("R_ID","COL1","M_ROW$$")
VALUES (:1,:2,:3)
最後一步, 刪除MVLOG中的值
delete from "ANYSQL"."MLOG$_T_MVLOG" where snaptime$$ <= :1
從這外過程來看, 可以調的方法有四個, 首先盡量使用快速重新整理, 提高重新整理頻率, 其次可以在MLOG$_T_MVLOG這個表的snaptime$$欄位上建索引, 第三為重新整理的過程設定會話級的DB_FILE_MULTIBLOCK_READ_COUNT以及SORT_AREA_SIZE等參數, 第四選擇時間對MLOG$_T_MVLOG這個表進行重組以減少表的大小. 這些方法僅供參考.