物化視圖是包括一個查詢結果的資料庫對象,它是遠端資料的的本地副本,或者用來生成基于資料表求和的彙總表。物化視圖存儲基于遠端表的資料,也可以稱為快照。對于複制,物化視圖允許你在本地維護遠端資料的副本 , 這些副本是隻讀的。如果你想修改本地副本,必須用進階複制的功能。當你想從一個表或視圖中抽取資料時,你可以用從物化視圖中抽取。 對于資料倉庫,建立的物化視圖通常情況下是聚合視圖,單一表聚合視圖和連接配接視圖。物化視圖可以查詢表,視圖和其它的物化視圖。
一、 關于物化視圖日志:
查詢物化視圖日志檔案格式:desc mlog$_lzwmvtest;
建立物化視圖時預設指定物化視圖中存在主鍵,如果不指定,那麼建立的物化視圖日志檔案的基表必須存在主鍵,否則會報錯
Demo:對一個表test
建立日志:create materialized view log on test;
那麼會報:表'LZWMVTEST'不包含主鍵限制條件
這種情況下,就必須指定日志檔案結構
比如:create materialized view log on test with rowid(具體的針對日志内容方面的在另外一個專題裡說明,這裡就簡述到此)
二、 關于生成資料和重新整理:
1>生成資料
兩大選項:build immediate build deferred
Build immediate:在建立物化視圖的同時根據主表生成資料
Bulid deferred:在建立物化視圖的同時,在物化視圖内不生成資料,如果此時沒有生成資料,以後可以采取:EXEC DBMS_MVIEW.Refresh(‘MV_name’,’C’),注意必須使用全量重新整理,預設是增量重新整理,是以這裡參數必須是C,因為之前都沒有生成資料,是以必須全量。
2>關于重新整理
² 重新整理方式:complete fast force
Complete :完全重新整理整個物化視圖,相當于重新生成物化視圖,此時即時增量重新整理可用也全量重新整理
Ø Fast:當有資料更新時依照相應的規則對物化視圖進行更新(此時必須建立物化視圖日志(物化視圖日志記錄了資料更新的日志),關于日志的說明,參照“物化視圖日志檔案介紹”)
Ø Force:當增量重新整理可用則增量重新整理,當增量重新整理不可用,則全量重新整理(此項為預設選項)
不過從實際情況出發,應該盡量不使用預設選項,可以考慮使用增量重新整理,對大表特别有效,大表全量更新速度是非常慢的,特别是在存在索引的情況下(在建立物化視圖語句中,可能某些限制查詢的條件,導緻了增量重新整理無法使用,這個是需要注意的,具體是哪類語句導緻fast重新整理不可用,有待總結…..)
² 重新整理時間:on demand on commit start with/ next
On demand:在需要重新整理時進行重新整理(人工判斷)
On commit:在基表上有送出操作時,進行更新
Start with:指定首次重新整理的時間(一般指定的是目前時間,不過也可以在建立物化視圖時不生成資料,則可以考慮在指定的時間重新整理,進而生成資料)
Next:重新整理的周期時間
三、 基于主鍵的物化視圖和ROWID的物化視圖的說明
建立物化視圖日志時,指定了記錄更新的原則即with 後面的primary 或者rowid 或者object id等等,後面,預設是以primary key為記錄更新,在物化視圖内也是以此為更新的原則。
例如:1、如果日志内使用的是primary key 則在建立物化視圖時指定rowid來更新,則會報ORA-12032: 不能使用 "TEST" 上實體化視圖日志中的 rowid 列
2、如過日志内使用的是rowid 則在建立物化視圖時指定primary或者預設指定,則會報ORA-23415: "GIS"."LZWMV" 的實體化視圖日志不記錄主鍵
四、 關于物化視圖存放的的表空間
直接在建立物化視圖時指定日志存放的表空間和物化視圖的表空間。
例子:create materialized view MV_TEST tablespace test ----表空間名稱
五、 關于查詢重寫和更新
在建立查詢重寫時,基表中必須有主鍵限制,視圖裡是無法建立主鍵的,不過其繼承了基表的主鍵限制。(關于視圖的建立的一些技巧有待總結……)下面給個例子
Create materialized view MV_TEST
Refresh fast ----前提是必須建立基表日志,可以忽略該項
Enable query rewrite ----前提是基表上必須存在主鍵限制
As
Select * from TEST; ----物化視圖資料生成
六、 關于建立物化視圖的例子:
1、 使用增量重新整理的物化視圖的寫法
建立物化視圖日志,必須建立日志
Create materialized view log on TEST ----TEST為表名
----注:(TEST為表名或者視圖名,關于視圖上建立物化視圖,見基于視圖的物化視圖
----建立物化視圖語句:
Create materialized view MV_TEST
----MVTEST為物化視圖名
Build immediate
----建立時生成資料對應的是build deferred
Refresh fast
----增量重新整理
On commit
----在基表有更新時送出,這裡該句對視圖無效
With rowid
----這裡建立基于rowid的物化視圖,對應的是 primary key
As
Select * from TEST;
----生成物化視圖資料語句
七、 小的知識點
建立主鍵限制語句:alter table table_name add(constraint constraint_name primary key(columes));
建議使用job來定期重新整理物化視圖
ORACLE物化視圖 全攻略
一、------------------------------------------------------------------------------------------
物化視圖是包括一個查詢結果的資料庫對像,它是遠端資料的的本地副本,或者用來生成基于資料表求和的彙總表。物化視圖存儲基于遠端表的資料,也可以稱為快照。
物化視圖可以查詢表,視圖和其它的物化視圖。
通常情況下,物化視圖被稱為主表(在複制期間)或明細表(在資料倉庫中)。
對于複制,物化視圖允許你在本地維護遠端資料的副本,這些副本是隻讀的。如果你想修改本地副本,必須用進階複制的功能。當你想從一個表或視圖中抽取資料時,你可以用從物化視圖中抽取。
對于資料倉庫,建立的物化視圖通常情況下是聚合視圖,單一表聚合視圖和連接配接視圖。
本篇我們将會看到怎樣建立物化視圖并且讨論它的重新整理選項。
在複制環境下,建立的物化視圖通常情況下主鍵,rowid,和子查詢視圖。
1.主鍵物化視圖:
下面的文法在遠端資料庫表emp上建立主鍵物化視圖
SQL> CREATE MATERIALIZED VIEWmv_emp_pk
REFRESH FAST START WITH SYSDATE
NEXTSYSDATE + 1/48
WITHPRIMARY KEY
ASSELECT * FROM [email protected]_db;
Materialized view created.
注意:當用FAST選項建立物化視圖,必須建立基于主表的視圖日志,如下:
SQL>CREATE MATERIALIZED VIEW LOG ON emp;
Materialized view log created.
2.Rowid物化視圖
下面的文法在遠端資料庫表emp上建立Rowid物化視圖
SQL> CREATE MATERIALIZED VIEWmv_emp_rowid
REFRESHWITH ROWID
AS SELECT * FROM [email protected]_db;
Materialized view log created.
3.子查詢物化視圖
下面的文法在遠端資料庫表emp上建立基于emp和dept表的子查詢物化視圖
SQL> CREATEMATERIALIZED VIEW mv_empdept
ASSELECT * FROM [email protected]_db e
WHEREEXISTS
(SELECT * FROM [email protected]_db d
WHEREe.dept_no = d.dept_no)
Materialized view log created.
REFRESH 子句
[refresh[fast|complete|force]
[ondemand | commit]
[startwith date] [next date]
[with{primary key|rowid}]]
Refresh選項說明:
a. oracle用重新整理方法在物化視圖中重新整理資料.
b. 是基于主鍵還是基于rowid的物化視圖
c. 物化視圖的重新整理時間和間隔重新整理時間
Refresh方法-FAST子句
增量重新整理用物化視圖日志(參照上面所述)來發送主表已經修改的資料行到物化視圖中.如果指定REFRESHFAST子句,那麼應該對主表建立物化視圖日志
SQL> CREATEMATERIALIZED VIEW LOG ON emp;
Materialized view log created.
對于增量重新整理選項,如果在子查詢中存在分析函數,則物化視圖不起作用。
Refresh方法-COMPLETE子句
完全重新整理重新生成整個視圖,如果請求完全重新整理,oracle會完成 完全重新整理即使增量重新整理可用。
Refresh Method – FORCE 子句
當指定FORCE子句,如果增量重新整理可用Oracle将完成增量重新整理,否則将完成完全重新整理,如果不指定重新整理方法(FAST,COMPLETE, or FORCE),Force選項是預設選項
主鍵和ROWD子句
WITHPRIMARY KEY選項生成主鍵物化視圖,也就是說物化視圖是基于主表的主鍵,而不是ROWID(對應于ROWID子句). PRIMARY KEY是預設選項,為了生成PRIMARY KEY子句,應該在主表上定義主鍵,否則應該用基于ROWID的物化視圖.
主鍵物化視圖允許識别物化視圖主表而不影響物化視圖增量重新整理的可用性。
Rowid物化視圖隻有一個單一的主表,不能包括下面任何一項:
n Distinct 或者聚合函數.
n Group by,子查詢,連接配接和SET操作
重新整理時間
START WITH子句通知資料庫完成從主表到本地表第一次複制的時間,應該及時估計下一次運作的時間點, NEXT 子句說明了重新整理的間隔時間.
SQL>CREATE MATERIALIZED VIEW mv_emp_pk
REFRESH FAST
START WITH SYSDATE
NEXT SYSDATE + 2
WITH PRIMARY KEY
AS SELECT * FROM [email protected]_db;
Materialized view created.
在上面的例子中,物化視圖資料的第一個副本在建立時生成,以後每兩天重新整理一次.
總結
物化視圖提供了可伸縮的基于主鍵或ROWID的視圖,指定了重新整理方法和自動重新整理的時間。
二、------------------------------------------------------------------------------------------
Oracle的物化視圖提供了強大的功能,可以用于預先計算并儲存表連接配接或聚集等耗時較多的操作的結果,這樣,在執行查詢時,就可以避免進行這些耗時的操作,而從快速的得到結果。物化視圖有很多方面和索引很相似:使用物化視圖的目的是為了提高查詢性能;物化視圖對應用透明,增加和删除物化視圖不會影響應用程式中SQL語句的正确性和有效性;物化視圖需要占用存儲空間;當基表發生變化時,物化視圖也應當重新整理。
物化視圖可以分為以下三種類型:包含聚集的物化視圖;隻包含連接配接的物化視圖;嵌套物化視圖。三種物化視圖的快速重新整理的限制條件有很大差別,而對于其他方面則差別不大。建立物化視圖時可以指定多種選項,下面對幾種主要的選擇進行簡單說明:
建立方式(Build Methods):包括BUILDIMMEDIATE和BUILD DEFERRED兩種。BUILDIMMEDIATE是在建立物化視圖的時候就生成資料,而BUILD DEFERRED則在建立時不生成資料,以後根據需要在生成資料。預設為BUILD IMMEDIATE。
查詢重寫(Query Rewrite):包括ENABLEQUERY REWRITE和DISABLE QUERY REWRITE兩種。分别指出建立的物化視圖是否支援查詢重寫。查詢重寫是指當對物化視圖的基表進行查詢時,Oracle會自動判斷能否通過查詢物化視圖來得到結果,如果可以,則避免了聚集或連接配接操作,而直接從已經計算好的物化視圖中讀取資料。預設為DISABLEQUERY REWRITE。
重新整理(Refresh):指當基表發生了DML操作後,物化視圖何時采用哪種方式和基表進行同步。重新整理的模式有兩種:ON DEMAND和ONCOMMIT。ON DEMAND指物化視圖在使用者需要的時候進行重新整理,可以手工通過DBMS_MVIEW.REFRESH等方法來進行重新整理,也可以通過JOB定時進行重新整理。ON COMMIT指出物化視圖在對基表的DML操作送出的同時進行重新整理。重新整理的方法有四種:FAST、COMPLETE、FORCE和NEVE*。**ST重新整理采用增量重新整理,隻重新整理自上次重新整理以後進行的修改。COMPLETE重新整理對整個物化視圖進行完全的重新整理。如果選擇FORCE方式,則Oracle在重新整理時會去判斷是否可以進行快速重新整理,如果可以則采用FAST方式,否則采用COMPLETE的方式。NEVER指物化視圖不進行任何重新整理。預設值是FORCE ONDEMAND。
在建立物化視圖的時候可以指定ORDER BY語句,使生成的資料按照一定的順序進行儲存。不過這個語句不會寫入物化視圖的定義中,而且對以後的重新整理也無效。
物化視圖日志:如果需要進行快速重新整理,則需要建立物化視圖日志。物化視圖日志根據不同物化視圖的快速重新整理的需要,可以建立為ROWID或PRIMARY KEY類型的。還可以選擇是否包括SEQUENCE、INCLUDING NEW VALUES以及指定列的清單。
可以指明ON PREBUILD TABLE語句将物化視圖建立在一個已經存在的表上。這種情況下,物化視圖和表必須同名。當删除物化視圖時,不會删除同名的表。這種物化視圖的查詢重寫要求參數QUERY_REWRITE_INTEGERITY必須設定為trusted或者stale_tolerated。
物化視圖可以進行分區。而且基于分區的物化視圖可以支援分區變化跟蹤(PCT)。具有這種特性的物化視圖,當基表進行了分區維護操作後,仍然可以進行快速重新整理操作。對于聚集物化視圖,可以在GROUPBY清單中使用CUBE或ROLLUP,來建立不同等級的聚集物化視圖。
物化視圖的基本操作和使用可以檢視網址:http://blog.itpub.net/post/468/13318相關的東東。我主要說明一下使用物化視圖的基本東東。如如何建立在特定的表空間上,這些在其他的物化視圖上面幾乎都沒有任何介紹的。主要以我做的一個例子來操作,
如果對物化視圖的基本概念清楚了就比較明白在那裡寫特定的表空間存儲了。
建立物化視圖時應先建立存儲的日志空間
CREATE MATERIALIZED VIEW LOG ON mv_lvy_levytaxbgtdiv
tablespace ZGMV_DATA --日志儲存在特定的表空間
WITH ROWID ;
CREATE MATERIALIZED VIEW LOG ON tb_lvy_levydetaildata
tablespace ZGMV_DATA --日志儲存在特定的表空間
WITH ROWID,sequence(LEVYDETAILDATAID);
CREATE MATERIALIZED VIEW LOG ON tb_lvy_levydata
tablespace ZGMV_DATA --日志儲存在特定的表空間
WITH rowid,sequence(LEVYDATAID);
然後建立物化視圖
--建立物化視圖
create materialized view MV_LVY_LEVYDETAILDATA
TABLESPACE ZGMV_DATA --儲存表空間
BUILD DEFERRED --延遲重新整理不立即重新整理
refresh force --如果可以快速重新整理則進行快速重新整理,否則完全重新整理
on demand --按照指定方式重新整理
start with to_date('24-11-2005 18:00:10', 'dd-mm-yyyy hh24:mi:ss') --第一次重新整理時間
next TRUNC(SYSDATE+1)+18/24 --重新整理時間間隔
as
SELECT levydetaildataid, detaildatano, taxtermbegin, taxtermend,
......
ROUND(taxdeduct * taxpercent1, 2) - ROUND(taxdeduct * taxpercent2, 2) -
ROUND(taxdeduct * taxpercent3, 2) - ROUND(taxdeduct * taxpercent4, 2) -
ROUND(taxdeduct * taxpercent5, 2) taxdeduct, ROUND(taxfinal * taxpercent1, 2) -
ROUND(taxfinal * taxpercent2, 2) - ROUND(taxfinal * taxpercent3, 2) -
ROUND(taxfinal * taxpercent4, 2) - ROUND(taxfinal * taxpercent5, 2) taxfinal,
a.levydataid, a.budgetitemcode, taxtypecode,
......
FROM tb_lvy_levydetaildata a, tb_lvy_levydata c, MV_LVY_LEVYTAXBGTDIV b
WHERE a.levydataid = c.levydataid
AND a.budgetdistrscalecode = b.budgetdistrscalecode
AND a.budgetitemcode = b.budgetitemcode
AND c.incomeresidecode = b.rcvfisccode
AND C.TAXSTATUSCODE='08'
AND C.NEGATIVEFLAG!='9'
删除物化視圖日志
--删除物化視圖:
--删除日志: DROP materialized view log onmv_lvy_levytaxbgtdiv;
DROP materialized view log on tb_lvy_levydetaildata;
DROP materialized view log on tb_lvy_levydata;
--删除物化視圖 drop materialized view MV_LVY_LEVYDETAILDATA;
--基本和對表的操作一緻 --物化視圖由于是實體真實存在的,故可以建立索引。
建立方式和對普通表建立方式相同,就不在重複寫了。
三、------------------------------------------------------------------------------------------
物化視圖對于前台資料庫使用者來說如同一個實際的表,具有和一般表相通的如select等操作,而其實際上是一個視圖,一個由系統實作定期重新整理其資料的視圖(具體重新整理時間在定義物化視圖的時候已有定義),使用物化視圖更可以實作視圖的所有功能,而物化視圖确不是在使用時才讀取,大大提高了讀取速度,特别适用抽取大資料量表某些資訊以及資料鍊連接配接表使用.具體文法如下:
物化視圖對于前台資料庫使用者來說如同一個實際的表,具有和表相通的一般select操作,而其實際上是一個視圖,一個定期重新整理資料的視圖(具體重新整理時間在定義物化視圖的時候已有定義),使用物化視圖可以實作視圖的所有功能,而物化視圖确不是在使用時才讀取,大大提高了讀取速度,特别适用抽取大資料量表某些資訊以及資料鍊連接配接表使用.具體文法如下:
CREATE MATERIALIZED VIEW an_user_base_file_no_charge
REFRESH COMPLETE START WITH SYSDATE
NEXT TRUNC(SYSDATE+29)+5.5/24
as
select distinct user_no
from cw_arrearage t
where (t.mon = dbms_tianjin.getLastMonth or
t.mon =add_months(dbms_tianjin.getLastMonth, -1))
drop materialized view an_user_base_file_no_charge;
第 13 章 物化視圖
8.1.5企業版/個人版開始支援
需要權限:GRANT CREATE MATERIALIZED VIEW,還必須直接賦予GRANT QUERYREWRITE.為實作查詢重寫,必須使用CBO.
13.1 物化視圖如何工作
設定
COMPATIBLE參數必須高于8.1.0
QUERY_REWRITE_ENABLED = TRUE
QUERY_REWRITE_INTEGRETY =
ENFORCED - 查詢僅用Oracle強制與保證的限制、規則重寫;
TRUSTED – 查詢除用Oracle強制與保證的限制、規則,也可用使用者設定的資料間的任何關系來重寫;
STALE_TOLERATED – 即便Oracle知道物化視圖中資料過期(與事實表等不同步),也重寫查詢。
建立物化視圖的使用者必須具有直接賦予的GRANT QUERY REWRITE權限,不能通過角色繼承。
内部機制
全文比對
部分比對:從FROM子句開始,優化器比較之後的文本,然後比較SELECT清單
一般重寫方法:
資料充分
關聯相容
分組相容
聚集相容
13.2 確定使用物化視圖
限制
考慮到現實環境的資料量,可以将主鍵、外鍵、非空等限制置為NOVALIDATE,并調整QUERY_REWRITE_INTEGRITY為TRUSTED,這樣可以達到“欺騙”資料庫的目的,但必須注意如果無法保證此類限制的真實有效,查詢改寫後可能造成結果不精确。
次元
實際就是指明已存在的表中各列的歸并關系,進而關聯事實表後形成的物化視圖可用于向“上”歸并(相當于用表中代表更高歸并關系的列關聯事實表)。标準文法:
CREATE DIMENSION time_hierarchy_dim
LEVEL day IS time_hierarchy.day
LEVEL mmyyyy IS time_hierarchy.mmyyyy
LEVEL yyyy IS time_hierarchy.yyyy
HIERARCHY time_rollup
(day CHILD OF mmyyyy CHILD OF yyyy)
ATTRIBUTE mmyyyy
DETERMINES mon_yyyy;
13.3 DBMS_OLAP
估計(物化視圖)大小
DBMS_OLAP.ESTIMATE_SUMMARY_SIZE(視圖名, 視圖定義, 估計行數, 估計位元組數);
其中後兩個參數為NUMBER型輸出參數。
次元有效性檢查
DBMS_OLAP.VALIDATE_DIMENSION(視圖名, 使用者名, FALSE, FALSE);
SELECT * FROM 次元表名
WHERE ROWIN IN (SEELCT bad_rowid FROM MVIEW$_EXCEPTION);
所選出行即為不符合次元定義的行。
推薦物化視圖
首先必須添加合适的外鍵,包通過外鍵來判定表之間的關系而不是次元。
DBMS_OLAP.RECOMMEND_MV(事實表名, 1000000000, ‘’);
第二個參數表示物化視圖可用的空間大小,可傳入一個較大的數。第三個參數傳入需要保留的特定物化視圖,傳入空即為不考慮其他物化視圖。
執行C:/oracle/RDBMS/demo/sadvdemo後執行:
DEMO_SUMADV.PRETTYPRINT_RECOMMENDATIONS
13.4 最後說明
物化視圖不為OLTP系統設計
在事實表等更新時會導緻物化視圖行鎖,進而影響系統并發性。
四、------------------------------------------------------------------------------------------
定位導緻物化視圖無法快速重新整理的原因
===========================================================
物化視圖的快速重新整理采用了增量的機制,在重新整理時,隻針對基表上發生變化的資料進行重新整理。是以快速重新整理是物化視圖重新整理方式的首選。
但是快速重新整理具有較多的限制,而且對于采用ON COMMIT模式進行快速重新整理的物化視圖更是如此。對于包含聚集和包含連接配接的物化視圖的快速重新整理機制并不相同,而且對于多層嵌套的物化視圖的快速重新整理更是有額外的要求。
如此多的限制一般很難記全,當建立物化視圖失敗時,Oracle給出的錯誤資訊又過于簡單,有時無法使你準确定位到問題的原因。
Oracle提供的DBMS_MVIEW.EXPLAIN_MVIEW過程可以幫助你快速定位問題的原因。下面通過一個例子來說明,如果通過這個過程來解決問題。
建立一個快速重新整理的嵌套物化視圖:
SQL> CREATE TABLE B (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30));
表已建立。
SQL> CREATE TABLE C (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30));
表已建立。
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));
表已建立。
SQL> INSERT INTO B SELECT ROWNUM, 'B'||ROWNUM FROM USER_TABLES WHERE ROWNUM<= 6;
已建立6行。
SQL> INSERT INTO C SELECT ROWNUM, 'C'||ROWNUM FROM USER_TABLES WHERE ROWNUM<= 4;
已建立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;
已建立12行。
SQL> COMMIT;
送出完成。
上面建立好基表,下面建立第一層物化視圖。
SQL> CREATE MATERIALIZED VIEW LOG ON A WITH ROWID;
實體化視圖日志已建立。
SQL> CREATE MATERIALIZED VIEW LOG ON B WITH ROWID;
實體化視圖日志已建立。
SQL> CREATE MATERIALIZED VIEW LOG ON C WITH ROWID;
實體化視圖日志已建立。
SQL> CREATE MATERIALIZED VIEW MV_ABC REFRESH FAST ON COMMIT ENABLE QUERYREWRITE 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;
實體化視圖已建立。
第一次物化視圖已經建立成功,下面建立嵌套物化視圖:
SQL> CREATE MATERIALIZED VIEW LOG ON MV_ABC WITH ROWID (BNAME, CNAME, NUM)INCLUDING NEW VALUES;
實體化視圖日志已建立。
SQL> CREATE MATERIALIZED VIEW MV_MV_ABC REFRESH FAST ON COMMIT ENABLE QUERYREWRITE AS
2 SELECT CNAME, BNAME, COUNT(*) COUNT, SUM(NUM) SUM_NUM FROMMV_ABC
3 GROUP BY CNAME, BNAME;
SELECT CNAME, BNAME, COUNT(*) COUNT, SUM(NUM) SUM_NUM FROM MV_ABC
*
ERROR 位于第 2 行:
ORA-12053: 這不是一個有效的嵌套實體化視圖
錯誤出現了,不過錯誤的描述包含的資訊量并不大。我們看看Oracle的文檔上是如何描述這個錯誤的。
ORA-12053 this is not a valid nested materialized view
Cause: The list of objects in the FROM clause of the definition of thismaterialized view had some dependencies upon each other.
Action: Refer to the documentation to see which types of nesting are valid.
文檔上的描述也是十分籠統的,并沒有指出具體問題所在。
接下來,我們通過使用DBMS_MVIEW.EXPLAIN_MVIEW過程來定位錯誤。
使用EXPLAIN_MVIEW過程首先要建立MV_CAPABILITIES_TABLE表,建表的腳步是$ORACLE_HOME/rdbms/admin/utlxmv.sql。(EXPLAIN_MVIEW過程是兩個過程的重載,一個輸出到MV_CAPABILITIES_TABLE表,另一個以PL/SQL的VARRAY格式輸出,為了簡單起見,我們建立MV_CAPABILITIES_TABLE表)。
SQL> @?rdbmsadminutlxmv.sql
表已建立。
下面簡單研究一下EXPLAIN_MVIEW過程。
DBMS_MVIEW.EXPLAIN_MVIEW(mv IN VARCHAR2, Statement_id IN VARCHAR2:= NULL);
該過程可以輸入已經存在的物化視圖名稱(或USER_NAME.MV_NAME),也可輸入建立物化視圖的查詢語句。另外一個參數STATEMENT_ID輸入一個語句ID,為了辨別出表中對應的記錄。
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 過程已成功完成。
SQL> SELECT CAPABILITY_NAME, RELATED_TEXT, MSGTXT FROM MV_CAPABILITIES_TABLE
2 WHERE STATEMENT_ID = 'MV_MV_ABC' AND POSSIBLE = 'N' ANDCAPABILITY_NAME NOT LIKE '%PCT%';
CAPABILITY_NAME RELATED_TEXT MSGTXT
------------------------------ -----------------------------------------------------------------
REFRESH_FAST_AFTER_ONETAB_DML SUM_NUM 使用 SUM(expr) 時, 未提供 COUNT(expr)
REFRESH_FAST_AFTER_ANY_DML YANGTK.MV_ABC mv日志沒有序列号
REFRESH_FAST_AFTER_ANY_DML 檢視禁用 REFRESH_FAST_AFTER_ONETAB_DML 的原因
根據上面的資訊,已經可以确定問題的原因了,對于聚集物化視圖,使用了SUM(COLUMN),但是沒有包括COUNT(COLUMN)。
修改物化視圖,重建立立:
SQL> CREATE MATERIALIZED VIEW MV_MV_ABC REFRESH FAST ON COMMIT ENABLE QUERYREWRITE AS
2 SELECT CNAME, BNAME, COUNT(*) COUNT, COUNT(NUM) NUM_COUNT,SUM(NUM) SUM_NUM FROM MV_ABC
3 GROUP BY CNAME, BNAME;
實體化視圖已建立。