物化视图刷新的问题及分析(61天)

作者: admin 分类: 公众号存档            0 次浏览 发布时间: 2014-05-03 09:32

公众号:杨建荣的学习笔记 · 作者:笔记61天 · 发布:2014-05-03 09:32:17 · 原文链接

最近现场需要搭建一套全新的环境,对于数据字典的管理采用了物化视图,因为数据量不大,采用了全量刷新的方式。因为有好几套环境,有几套环境是通过db link和主节点的表创建的物化视图,这几个节点间的网络情况不好,刷新一个稍微大一些的表或者带有lob字段的表时,速度会很慢,因为有好几套环境,一套一套的等待刷新完得花费不少的时间,所以自己想写一个shell脚本让它在后台慢慢跑,这样过一段时间再看看日志保证数据都已经刷新完毕就可以了。
原本采用的方式是
create materialized view xxx as select *from xxxx@xxxx;
刷新的速度确实太慢,
然后自己灵机一动,想先创建物化视图,然后让它在后台慢慢刷新,类似下面的方式
create materialized view xxxx as select *from xxx@xxxx where rownum<1;
exec dbms_mview.refresh(‘XXXX’,’C’);
这样先创建完成后慢慢刷新就可以了,我也可以先把权限之类的先分配好,直接能够访问。

简单的写了个脚本测试了一下,发现速度确实快了不少,创建和刷新的速度都奇快。
第二天,开发反馈很多数据字典都是空的。自己先查看刷新日志,发现都是刷新过的。然后怀疑是不是数据的刷新问题,又手工刷新了一次,发现基表的数据有好几十条,但是刷新之后还是0条,接连试了几次,还是0条,感觉就像是bug一样。
最后才算想明白,就是自己的一个小聪明导致的,其实下面的语句在table和materialized view中代表的意义是不同的。

create table test as select *from xxxx where rownum<1;

create materialized view test as select *from xxxx where rownum<1;

下面简单来做一个测试,说明一下。
创建测试的物化视图test_mv,有5条数据。
SQL> create materialized view test_mv as select *from cat;
Materialized view created.
SQL> select count(*)from test_mv;
COUNT(*)
———-
5

然后删除物化视图,重建
SQL> drop materialized view test_mv;
Materialized view dropped.

SQL> Create materialized view test_mv as select *from cat where rownum<1;
Materialized view created.

SQL> select count(*)from test_mv;
COUNT(*)
———-
0
然后开始全量刷新,刷新之后数据条数还是0条。无论刷新多少次都是0条。

SQL> exec dbms_mview.refresh(‘TEST_MV’,’C’);
PL/SQL procedure successfully completed.

SQL> select count(*)from test_mv;
COUNT(*)
———-
0

其中的奥秘就在于(使用dbms_metadata来查看物化视图的创建语句)
SQL> select dbms_metadata.get_ddl(‘MATERIALIZED_VIEW’,’TEST_MV’) from dual;
CREATE MATERIALIZED VIEW “N1″.”TEST_MV” (“TABLE_NAME”, “TABLE_TYPE”)
ORGANIZATION HEAP PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE “TEST_DATA2”
BUILD IMMEDIATE
USING INDEX
REFRESH FORCE ON DEMAND
USING DEFAULT LOCAL ROLLBACK SEGMENT
USING ENFORCED CONSTRAINTS DISABLE QUERY REWRITE
AS select *from cat where rownum<1

在创建物化视图的时候,它会在末尾加上一个rownum<1,这样就使得无论怎么刷新,数据都进不来,所以仔细想想,物化视图在这个时候有点视图的意思。

最后对于那个问题的解决方式就是重新来创建物化视图.

admin

杨建荣,《Oracle DBA工作笔记》《MySQL DBA工作笔记》作者,dbaplus社群发起人之一,腾讯云TVP,现任竞技世界系统部经理,拥有十多年数据库开发和运维经验,目前专注于开源技术、运维自动化和性能调优

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注