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

dbhelper發表於2014-11-27
最近現場需要搭建一套全新的環境,對於資料字典的管理採用了物化檢視,因為資料量不大,採用了全量重新整理的方式。因為有好幾套環境,有幾套環境是透過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,這樣就使得無論怎麼重新整理,資料都進不來,所以仔細想想,物化檢視在這個時候有點檢視的意思。

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

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8494287/viewspace-1349346/,如需轉載,請註明出處,否則將追究法律責任。

相關文章