Oracle的实体化视图(MVIEW)的深入研究之一

时间:2023-02-01 19:43:53

 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这个表进行重组以减少表的大小. 这些方法仅供参考.