ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 包含LOB的物化视图快速刷新(四)

包含LOB的物化视图快速刷新(四)

原创 Linux操作系统 作者:yangtingkun 时间:2009-11-22 22:33:47 0 删除 编辑

以前写过一篇文章描述物化视图是否进行字段级的刷新。当时得出的结论是包含LOB字段的物化视图会进行字段级的刷新,但是这个结论是在9.2上得出的,最近测试发现,10g上的结果有所不同。

这篇文章对比9i和11g包含LOB的物化视图的刷新性能。

包含LOB的物化视图快速刷新:http://yangtingkun.itpub.net/post/468/493060

包含LOB的物化视图快速刷新(二):http://yangtingkun.itpub.net/post/468/493206

包含LOB的物化视图快速刷新(三):http://yangtingkun.itpub.net/post/468/493660

物化视图是否根据字段进行刷新(一):http://yangtingkun.itpub.net/post/468/201236

物化视图是否根据字段进行刷新(二):http://yangtingkun.itpub.net/post/468/201607

物化视图是否根据字段进行刷新(三):http://yangtingkun.itpub.net/post/468/203414

 

 

有了前面几篇文章中理论的基础,这里做一个简单的测试,分别在9.2和11.2上执行物化视图的刷新。为了公平,不同版本的两个数据库处于同一台服务器上,而且二者的SGA也相差不大。

SQL> set sqlp 'SQL9.2> '
SQL9.2> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production
PL/SQL Release 9.2.0.4.0 - Production
CORE    9.2.0.3.0       Production
TNS for Linux: Version 9.2.0.4.0 - Production
NLSRTL Version 9.2.0.4.0 - Production

SQL9.2> host hostname
bjtest

SQL9.2> show sga

Total System Global Area 5121220856 bytes
Fixed Size                   749816 bytes
Variable Size             822083584 bytes
Database Buffers         4294967296 bytes
Redo Buffers                3420160 bytes

上面是9.2的会话,下面的会话连接的是11.2:

SQL> set sqlp 'SQL11.2> '
SQL11.2> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

SQL11.2> host hostname
bjtest

SQL11.2> show sga

Total System Global Area 6814535680 bytes
Fixed Size                  2214016 bytes
Variable Size            4093642624 bytes
Database Buffers         2684354560 bytes
Redo Buffers               34324480 bytes

首先对比一下包含大量内容的LOB的物化视图的刷新:

SQL9.2> CREATE TABLE T
  2  (
  3     ID NUMBER,
  4     NAME VARCHAR2(30),
  5     CONTENTS CLOB,
  6     CONSTRAINT PK_T PRIMARY KEY (ID)
  7  );

表已创建。

SQL9.2> DECLARE
  2     V_LOB CLOB;
  3     V_STR VARCHAR2(32767) := RPAD('A', 32767, 'A');
  4  BEGIN
  5     INSERT INTO T VALUES (1, 'TEST', EMPTY_CLOB) RETURN CONTENTS INTO V_LOB;
  6     FOR I IN 1..1000 LOOP
  7             DBMS_LOB.WRITEAPPEND(V_LOB, LENGTH(V_STR), V_STR);
  8     END LOOP;
  9     COMMIT;
 10  END;
 11  /

PL/SQL 过程已成功完成。

SQL9.2> CREATE MATERIALIZED VIEW LOG ON T;

实体化视图日志已创建。

SQL9.2> CREATE MATERIALIZED VIEW MV_T REFRESH FAST AS
  2  SELECT *
  3  FROM T;

实体化视图已创建。

SQL9.2> UPDATE T
  2  SET NAME = 'ABC'
  3  WHERE ID = 1;

已更新 1 行。

SQL9.2> COMMIT;

提交完成。

SQL9.2> SET TIMING ON
SQL9.2> EXEC DBMS_MVIEW.REFRESH('MV_T')

PL/SQL 过程已成功完成。

已用时间:  00: 00: 00.40
SQL9.2> SELECT ID, NAME
  2  FROM T;

        ID NAME
---------- ------------------------------
         1 ABC

看看11.2的情况,执行同样的操作:

SQL11.2> CREATE TABLE T
  2  (
  3     ID NUMBER,
  4     NAME VARCHAR2(30),
  5     CONTENTS CLOB,
  6     CONSTRAINT PK_T PRIMARY KEY (ID)
  7  );

表已创建。

SQL11.2> DECLARE
  2     V_LOB CLOB;
  3     V_STR VARCHAR2(32767) := RPAD('A', 32767, 'A');
  4  BEGIN
  5     INSERT INTO T VALUES (1, 'TEST', EMPTY_CLOB) RETURN CONTENTS INTO V_LOB;
  6     FOR I IN 1..1000 LOOP
  7             DBMS_LOB.WRITEAPPEND(V_LOB, LENGTH(V_STR), V_STR);
  8     END LOOP;
  9     COMMIT;
 10  END;
 11  /

PL/SQL 过程已成功完成。

SQL11.2> CREATE MATERIALIZED VIEW LOG ON T;

实体化视图日志已创建。

SQL11.2> CREATE MATERIALIZED VIEW MV_T REFRESH FAST AS
  2  SELECT *
  3  FROM T;

实体化视图已创建。

SQL11.2> UPDATE T
  2  SET NAME = 'ABC'
  3  WHERE ID = 1;

已更新 1 行。

SQL11.2> COMMIT;

提交完成。

SQL11.2> SET TIMING ON
SQL11.2> EXEC DBMS_MVIEW.REFRESH('MV_T')

PL/SQL 过程已成功完成。

已用时间:  00: 00: 02.12
SQL11.2> SELECT ID, NAME
  2  FROM T;

        ID NAME
---------- ------------------------------
         1 ABC

由于9i中不需要更新LOB列,因此物化视图的刷新只用了0.4秒,而11.2比9.2高了2个大版本、4个小版本,但是由于需要更新不必要的LOB列,因此花费了2秒多的时间来刷新物化视图。

下面在看看LOB长度为32767的LOB的刷新问题:

SQL9.2> DELETE T;

已删除 1 行。

已用时间:  00: 00: 00.13
SQL9.2> DECLARE
  2     V_STR VARCHAR2(32767) := RPAD('A', 32767, 'A');
  3  BEGIN
  4     FOR I IN 1..1000 LOOP
  5             INSERT INTO T VALUES (I, 'TEST', V_STR);
  6     END LOOP;
  7     COMMIT;
  8  END;
  9  /

PL/SQL 过程已成功完成。

已用时间:  00: 00: 13.27
SQL9.2> COMMIT;

提交完成。

已用时间:  00: 00: 00.00
SQL9.2> EXEC DBMS_MVIEW.REFRESH('MV_T')

PL/SQL 过程已成功完成。

已用时间:  00: 00: 17.02
SQL9.2> UPDATE T SET NAME = 'ABC';

已更新1000行。

已用时间:  00: 00: 00.10
SQL9.2> COMMIT;

提交完成。

已用时间:  00: 00: 00.01
SQL9.2> EXEC DBMS_MVIEW.REFRESH('MV_T')

PL/SQL 过程已成功完成。

已用时间:  00: 00: 00.32

由于没有更新LOB列,物化视图的刷新只用了0.32秒,下面看看11.2的情况:

SQL11.2> DELETE T;

已删除 1 行。

已用时间:  00: 00: 00.24
SQL11.2> DECLARE
  2     V_STR VARCHAR2(32767) := RPAD('A', 32767, 'A');
  3  BEGIN
  4     FOR I IN 1..1000 LOOP
  5             INSERT INTO T VALUES (I, 'TEST', V_STR);
  6     END LOOP;
  7     COMMIT;
  8  END;
  9  /

PL/SQL 过程已成功完成。

已用时间:  00: 00: 03.18
SQL11.2> COMMIT;

提交完成。

已用时间:  00: 00: 00.00
SQL11.2> EXEC DBMS_MVIEW.REFRESH('MV_T')

PL/SQL 过程已成功完成。

已用时间:  00: 00: 10.41
SQL11.2> UPDATE T SET NAME = 'ABC';

已更新1000行。

已用时间:  00: 00: 00.09
SQL11.2> COMMIT;

提交完成。

已用时间:  00: 00: 00.00
SQL11.2> EXEC DBMS_MVIEW.REFRESH('MV_T')

PL/SQL 过程已成功完成。

已用时间:  00: 00: 11.48

对于11.2的情况,由于物化视图的刷新没有对LOB列单独处理,且当LOB列的数据长度为32767时,会进行两次更新,导致物化视图的刷新时间将近11.5秒。

对比上面所有的操作,基本上都是11.2的处理能力要比9.2效率高,但是在包含LOB的物化视图刷新上,显然9i中的处理更加合理。

不知道是bug的原因还是Oracle出于其他的考虑,导致10g以后的版本在包含LOB的物化视图的刷新问题上,没有再采用列级的方式,从而导致了物化视图刷新性能的降低。

 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4227/viewspace-620255/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1964
  • 访问量
    11076237