天天看點

物化視圖重新整理的問題及分析

最近現場需要搭建一套全新的環境,對于資料字典的管理采用了物化視圖,因為資料量不大,采用了全量重新整理的方式。因為有好幾套環境,有幾套環境是通過db link和主節點的表建立的物化視圖,這幾個節點間的網絡情況不好,重新整理一個稍微大一些的表或者帶有lob字段的表時,速度會很慢,因為有好幾套環境,一套一套的等待重新整理完得花費不少的時間,是以自己想寫一個shell腳本讓它在背景慢慢跑,這樣過一段時間再看看日志保證資料都已經重新整理完畢就可以了。

原本采用的方式是

create materialized view xxx as select *from xxxx@xxxx;

重新整理的速度确實太慢,

然後自己靈機一動,想先建立物化視圖,然後讓它在背景慢慢重新整理,類似下面的方式

create materialized view xxxx as select *from xxx@xxxx where rownum

exec dbms_mview.refresh('XXXX','C');

這樣先建立完成後慢慢重新整理就可以了,我也可以先把權限之類的先配置設定好,直接能夠通路。

簡單的寫了個腳本測試了一下,發現速度确實快了不少,建立和重新整理的速度都奇快。

第二天,開發回報很多資料字典都是空的。自己先檢視重新整理日志,發現都是重新整理過的。然後懷疑是不是資料的重新整理問題,又手工重新整理了一次,發現基表的資料有好幾十條,但是重新整理之後還是0條,接連試了幾次,還是0條,感覺就像是bug一樣。

最後才算想明白,就是自己的一個小聰明導緻的,其實下面的語句在table和materialized view中代表的意義是不同的。

create table test as select *from xxxx where rownum

create materialized view test as select *from xxxx where rownum

下面簡單來做一個測試,說明一下。

建立測試的物化視圖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

然後開始全量重新整理,重新整理之後資料條數還是0條。無論重新整理多少次都是0條。

SQL> exec dbms_mview.refresh('TEST_MV','C');

PL/SQL procedure successfully completed.

其中的奧秘就在于(使用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

在建立物化視圖的時候,它會在末尾加上一個rownum

最後對于那個問題的解決方式就是重新來建立物化視圖.