定位导致物化视图无法快速刷新的原因
轉(zhuǎn)載自:http://yangtingkun.itpub.net/post/468/13318
物化視圖的快速刷新采用了增量的機(jī)制,在刷新時(shí),只針對(duì)基表上發(fā)生變化的數(shù)據(jù)進(jìn)行刷新。因此快速刷新是物化視圖刷新方式的首選。
但是快速刷新具有較多的約束,而且對(duì)于采用ON COMMIT模式進(jìn)行快速刷新的物化視圖更是如此。對(duì)于包含聚集和包含連接的物化視圖的快速刷新機(jī)制并不相同,而且對(duì)于多層嵌套的物化視圖的快速刷新更是有額外的要求。
如此多的限制一般很難記全,當(dāng)建立物化視圖失敗時(shí),Oracle給出的錯(cuò)誤信息又過(guò)于簡(jiǎn)單,有時(shí)無(wú)法使你準(zhǔn)確定位到問(wèn)題的原因。
Oracle提供的DBMS_MVIEW.EXPLAIN_MVIEW過(guò)程可以幫助你快速定位問(wèn)題的原因。下面通過(guò)一個(gè)例子來(lái)說(shuō)明,如果通過(guò)這個(gè)過(guò)程來(lái)解決問(wèn)題。
?
建立一個(gè)快速刷新的嵌套物化視圖:
SQL> CREATE TABLE B (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30));
表已創(chuàng)建。
SQL> CREATE TABLE C (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30));
表已創(chuàng)建。
SQL> CREATE TABLE A (ID NUMBER, BID NUMBER, CID NUMBER, NUM NUMBER,?
? 2? CONSTRAINT FK_A_B_BID FOREIGN KEY (BID) REFERENCES B(ID),?
? 3? CONSTRAINT FK_A_C_BID FOREIGN KEY (CID) REFERENCES C(ID));
表已創(chuàng)建。
SQL> INSERT INTO B SELECT ROWNUM, 'B'||ROWNUM FROM USER_TABLES WHERE ROWNUM <= 6;
已創(chuàng)建6行。
SQL> INSERT INTO C SELECT ROWNUM, 'C'||ROWNUM FROM USER_TABLES WHERE ROWNUM <= 4;
已創(chuàng)建4行。
SQL> INSERT INTO A SELECT ROWNUM, TRUNC((ROWNUM - 1)/2) + 1, TRUNC((ROWNUM - 1)/3) + 1, ROWNUM?
? 2? FROM USER_TABLES
? 3? WHERE ROWNUM <= 12;
已創(chuàng)建12行。
SQL> COMMIT;
提交完成。
上面建立好基表,下面建立第一層物化視圖。
SQL> CREATE MATERIALIZED VIEW LOG ON A WITH ROWID;
實(shí)體化視圖日志已創(chuàng)建。
SQL> CREATE MATERIALIZED VIEW LOG ON B WITH ROWID;
實(shí)體化視圖日志已創(chuàng)建。
SQL> CREATE MATERIALIZED VIEW LOG ON C WITH ROWID;
實(shí)體化視圖日志已創(chuàng)建。
SQL> CREATE MATERIALIZED VIEW MV_ABC REFRESH FAST ON COMMIT ENABLE QUERY REWRITE AS
? 2? SELECT C.ID CID, C.NAME CNAME, B.ID BID, B.NAME BNAME, A.NUM,?
? 3? A.ROWID AROWID, B.ROWID BROWID, C.ROWID CROWID?
? 4? FROM A, B, C WHERE A.BID = B.ID AND A.CID = C.ID;
實(shí)體化視圖已創(chuàng)建。
第一次物化視圖已經(jīng)建立成功,下面建立嵌套物化視圖:
SQL> CREATE MATERIALIZED VIEW LOG ON MV_ABC WITH ROWID (BNAME, CNAME, NUM) INCLUDING NEW VALUES;
實(shí)體化視圖日志已創(chuàng)建。
SQL> CREATE MATERIALIZED VIEW MV_MV_ABC REFRESH FAST ON COMMIT ENABLE QUERY REWRITE AS
? 2? SELECT CNAME, BNAME, COUNT(*) COUNT, SUM(NUM) SUM_NUM FROM MV_ABC
? 3? GROUP BY CNAME, BNAME;
SELECT CNAME, BNAME, COUNT(*) COUNT, SUM(NUM) SUM_NUM FROM MV_ABC
?????????????????????????????????????????????????????????? *
ERROR 位于第 2 行:
ORA-12053: 這不是一個(gè)有效的嵌套實(shí)體化視圖
錯(cuò)誤出現(xiàn)了,不過(guò)錯(cuò)誤的描述包含的信息量并不大。我們看看Oracle的文檔上是如何描述這個(gè)錯(cuò)誤的。
ORA-12053 this is not a valid nested materialized view
Cause:?The list of objects in the FROM clause of the definition of this materialized view had some dependencies upon each other.
Action:?Refer to the documentation to see which types of nesting are valid.
文檔上的描述也是十分籠統(tǒng)的,并沒(méi)有指出具體問(wèn)題所在。
接下來(lái),我們通過(guò)使用DBMS_MVIEW.EXPLAIN_MVIEW過(guò)程來(lái)定位錯(cuò)誤。
使用EXPLAIN_MVIEW過(guò)程首先要建立MV_CAPABILITIES_TABLE表,建表的腳步是$ORACLE_HOME/rdbms/admin/utlxmv.sql。(EXPLAIN_MVIEW過(guò)程是兩個(gè)過(guò)程的重載,一個(gè)輸出到MV_CAPABILITIES_TABLE表,另一個(gè)以PL/SQL的VARRAY格式輸出,為了簡(jiǎn)單起見(jiàn),我們建立MV_CAPABILITIES_TABLE表)。
SQL> @?rdbmsadminutlxmv.sql
表已創(chuàng)建。
下面簡(jiǎn)單研究一下EXPLAIN_MVIEW過(guò)程。
DBMS_MVIEW.EXPLAIN_MVIEW(mv IN VARCHAR2, Statement_id IN VARCHAR2:= NULL);
該過(guò)程可以輸入已經(jīng)存在的物化視圖名稱(chēng)(或USER_NAME.MV_NAME),也可輸入建立物化視圖的查詢(xún)語(yǔ)句。另外一個(gè)參數(shù)STATEMENT_ID輸入一個(gè)語(yǔ)句ID,為了標(biāo)識(shí)出表中對(duì)應(yīng)的記錄。
SQL> BEGIN
? 2? DBMS_MVIEW.EXPLAIN_MVIEW('SELECT CNAME, BNAME, COUNT(*) COUNT, SUM(NUM) SUM_NUM FROM MV_ABC?
? 3? GROUP BY CNAME, BNAME', 'MV_MV_ABC');
? 4? END;
? 5? /
PL/SQL 過(guò)程已成功完成。
SQL> SELECT CAPABILITY_NAME, RELATED_TEXT, MSGTXT FROM MV_CAPABILITIES_TABLE
? 2? WHERE STATEMENT_ID = 'MV_MV_ABC' AND POSSIBLE = 'N' AND CAPABILITY_NAME NOT LIKE '%PCT%';
CAPABILITY_NAME??????????????? RELATED_TEXT??? MSGTXT
------------------------------ --------------- --------------------------------------------------
REFRESH_FAST_AFTER_ONETAB_DML? SUM_NUM???????? 使用 SUM(expr) 時(shí), 未提供 COUNT(expr)
REFRESH_FAST_AFTER_ANY_DML???? YANGTK.MV_ABC?? mv 日志沒(méi)有序列號(hào)
REFRESH_FAST_AFTER_ANY_DML???????????????????? 查看禁用 REFRESH_FAST_AFTER_ONETAB_DML 的原因
根據(jù)上面的信息,已經(jīng)可以確定問(wèn)題的原因了,對(duì)于聚集物化視圖,使用了SUM(COLUMN),但是沒(méi)有包括COUNT(COLUMN)。
修改物化視圖,重新建立:
SQL> CREATE MATERIALIZED VIEW MV_MV_ABC REFRESH FAST ON COMMIT ENABLE QUERY REWRITE AS
? 2? SELECT CNAME, BNAME, COUNT(*) COUNT, COUNT(NUM) NUM_COUNT, SUM(NUM) SUM_NUM FROM MV_ABC
? 3? GROUP BY CNAME, BNAME;
實(shí)體化視圖已創(chuàng)建。
總結(jié)
以上是生活随笔為你收集整理的定位导致物化视图无法快速刷新的原因的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在shell脚本中调用sqlplus
- 下一篇: 段的创建表user_segments