Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103678563
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: Oracle

2008-05-23 13:14:50

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

阅读(245) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~