Oracle物化視圖的用法與總結(jié)
物化視圖(material view)是什么?
物化視圖是包括一個(gè)查詢結(jié)果的數(shù)據(jù)庫對(duì)象,它是遠(yuǎn)程數(shù)據(jù)的的本地副本,或者用來生成基于數(shù)據(jù)表求和的匯總表。
物化視圖存儲(chǔ)基于遠(yuǎn)程表的數(shù)據(jù),也可以稱為快照(類似于MSSQL Server中的snapshot,靜態(tài)快照)。對(duì)于復(fù)制,物化視圖允許你在本地維護(hù)遠(yuǎn)程數(shù)據(jù)的副本,這些副本是只讀的。
如果你想修改本地副本,必須用高級(jí)復(fù)制的功能。當(dāng)你想從一個(gè)表或視圖中抽取數(shù)據(jù)時(shí),你可以用從物化視圖中抽取。
對(duì)于數(shù)據(jù)倉庫,創(chuàng)建的物化視圖通常情況下是聚合視圖,單一表聚合視圖和連接視圖。(這個(gè)是基于本地的基表或者視圖的聚合)。
物化視圖,說白了,就是物理表,只不過這張表通過oracle的內(nèi)部機(jī)制可以定期更新,將一些大的耗時(shí)的表連接用物化視圖實(shí)現(xiàn),會(huì)提高查詢的效率。當(dāng)然要打開查詢重寫選項(xiàng);
簡(jiǎn)而言之,就是具有實(shí)體表的視圖,而且這個(gè)視圖還可以根據(jù)多種需求和策略進(jìn)行刷新。此外還有一個(gè)非常重要的功能
查詢重寫(query rewrite) .查詢重寫能夠在某些時(shí)候提高你的查詢速度。
所謂查詢重寫,簡(jiǎn)而言之,就是oracle 的查詢優(yōu)化器發(fā)現(xiàn)有個(gè)物化視圖的語法和你的SQL差不多,那么就會(huì)直接訪問物化視圖,而不是你原來查詢中有關(guān)的源表。
物化視圖能干什么?
或者說,你能拿物化視圖做什么用。
前文簡(jiǎn)單說了下,此處列出一些重要而想詳細(xì)的功能:
- 能夠提高查詢速度,這主要是因?yàn)槲锘晥D存儲(chǔ)了實(shí)際的數(shù)據(jù),其次具有查詢重寫功能。最后,物化視圖具有實(shí)體表,你也可以在上面建立索引,總之大體上當(dāng)作一個(gè)表用就可以了。
- 簡(jiǎn)化了開發(fā)任務(wù),意思是開發(fā)的人員有的時(shí)候,無需直接關(guān)注部分sql的性能,而通過dba的努力,使用查詢重寫來完成性能的提升。
- 減少了工作量,因?yàn)槲锘晥D可以定義兩種刷新方式:立即刷新,按需刷新。所謂按需刷新就是你自己手動(dòng)刷新,或者是定時(shí)刷新;所謂立即刷新,即視圖主表發(fā)生變化的時(shí)候,視圖立即刷新內(nèi)容。 你可以根據(jù)自己的設(shè)備情況,應(yīng)用情況和需求來控制刷新的方式。
- 刷新量的靈活限制,你可以快速是刷新(只刷新變化的),也可以全刷新。看你的需要。
物化視圖可以分為以下三種類型
- 包含聚集的物化視圖;
- 只包含連接的物化視圖;
- 嵌套物化視圖。
三種物化視圖的快速刷新的限制條件有很大區(qū)別,而對(duì)于其他方面則區(qū)別不大。創(chuàng)建物化視圖時(shí)可以指定多種選項(xiàng),下面對(duì)幾種主要的選擇進(jìn)行簡(jiǎn)單說明:
創(chuàng)建方式(BuildMethods):包括BUILD IMMEDIATE和BUILD DEFERRED兩種。
BUILD IMMEDIATE是在創(chuàng)建物化視圖的時(shí)候就生成數(shù)據(jù)。
BUILD DEFERRED則在創(chuàng)建時(shí)不生成數(shù)據(jù),以后根據(jù)需要在生成數(shù)據(jù)。默認(rèn)為BUILD IMMEDIATE。查詢重寫(QueryRewrite):包括ENABLE QUERY REWRITE和DISABLE QUERY REWRITE兩種。
分別指出創(chuàng)建的物化視圖是否支持查詢重寫。查詢重寫是指當(dāng)對(duì)物化視圖的基表進(jìn)行查詢時(shí),Oracle會(huì)自動(dòng)判斷能否通過查詢物化視圖來得到結(jié)果,如果可以,則避免了聚集或連接操作,而直接從已經(jīng)計(jì)算好的物化視圖中讀取數(shù)據(jù)。默認(rèn)為DISABLE QUERY REWRITE。刷新(Refresh):指當(dāng)基表發(fā)生了DML操作后,物化視圖何時(shí)采用哪種方式和基表進(jìn)行同步。刷新的模式有兩種:ON DEMAND和ON COMMIT。ON DEMAND和ON COMMIT物化視圖的區(qū)別在于其刷新方法的不同,ON DEMAND指物化視圖在用戶需要的時(shí)候進(jìn)行刷新,可以手工通過DBMS_MVIEW.REFRESH等方法來進(jìn)行刷新,也可以通過JOB定時(shí)進(jìn)行刷新,即更新物化視圖,以保證和基表數(shù)據(jù)的一致性;而ON COMMIT是說,一旦基表有了COMMIT,即事務(wù)提交,則立刻刷新,立刻更新物化視圖,使得數(shù)據(jù)和基表一致。對(duì)基表,平常的COMMIT在0.01秒內(nèi)可以完成,但在有了ON COMMIT視圖后,居然要6秒。速度減低了很多倍。ON COMMIT視圖對(duì)基表的影響可見一斑。
物化視圖,根據(jù)不同的著重點(diǎn)可以有不同的分類:
- 按刷新方式分:FAST/COMPLETE/FORCE
- 按刷新時(shí)間的不同:ON DEMAND/ON COMMIT
- 按是否可更新:UPDATABLE/READ ONLY
- 按是否支持查詢重寫:ENABLE QUERY REWRITE/DISABLEQUERY REWRITE
默認(rèn)情況下,如果沒指定刷新方法和刷新模式,則Oracle默認(rèn)為FORCE和DEMAND。
注意:設(shè)置REFRESH ON COMMIT的物化視圖不能訪問遠(yuǎn)端對(duì)象。
在建立物化視圖的時(shí)候可以指定ORDER BY語句,使生成的數(shù)據(jù)按照一定的順序進(jìn)行保存。不過這個(gè)語句不會(huì)寫入物化視圖的定義中,而且對(duì)以后的刷新也無效。
物化視圖有三種刷新方式:COMPLETE、FAST和 FORCE。
- 完全刷新(COMPLETE)會(huì)刪除表中所有的記錄(如果是單表刷新,可能會(huì)采用TRUNCATE的方式),然后根據(jù)物化視圖中查詢語句的定義重新生成物化視圖。
- 快速刷新(FAST)采用增量刷新的機(jī)制,只將自上次刷新以后對(duì)基表進(jìn)行的所有操作刷新到物化視圖中去。FAST必須創(chuàng)建基于主表的視圖日志。對(duì)于增量刷新選項(xiàng),如果在子查詢中存在分析函數(shù),則物化視圖不起作用。
- 采用FORCE方式,Oracle會(huì)自動(dòng)判斷是否滿足快速刷新的條件,如果滿足則進(jìn)行快速刷新,否則進(jìn)行完全刷新。
Oracle物化視圖的快速刷新機(jī)制是通過物化視圖日志完成的。Oracle通過一個(gè)物化視圖日志還可以支持多個(gè)物化視圖的快速刷新。物化視圖日志根據(jù)不同物化視圖的快速刷新的需要,可以建立為ROWID或PRIMARY KEY類型的。還可以選擇是否包括SEQUENCE、INCLUDING NEW VALUES以及指定列的列表。
物化視圖操作示例
-- 物化視圖操作示例
-- 刪除物化視圖
DROP MATERIALIZED VIEW V_RPT_ACT_ACTION;
-- 創(chuàng)建物化視圖
/**
1.創(chuàng)建方式(BuildMethods):包括BUILD IMMEDIATE和BUILD DEFERRED兩種。
BUILD IMMEDIATE是在創(chuàng)建物化視圖的時(shí)候就生成數(shù)據(jù)。
BUILD DEFERRED則在創(chuàng)建時(shí)不生成數(shù)據(jù),以后根據(jù)需要在生成數(shù)據(jù)。默認(rèn)為BUILD IMMEDIATE。
2. 查詢重寫(QueryRewrite):包括ENABLE QUERY REWRITE和DISABLE QUERY REWRITE兩種。
分別指出創(chuàng)建的物化視圖是否支持查詢重寫。
查詢重寫是指當(dāng)對(duì)物化視圖的基表進(jìn)行查詢時(shí),
Oracle會(huì)自動(dòng)判斷能否通過查詢物化視圖來得到結(jié)果,如果可以,則避免了聚集或連接操作,
而直接從已經(jīng)計(jì)算好的物化視圖中讀取數(shù)據(jù)。默認(rèn)為DISABLE QUERY REWRITE。
*/
CREATE MATERIALIZED VIEW V_RPT_ACT_ACTION
BUILD IMMEDIATE
DISABLE QUERY REWRITE
AS
SELECT * FROM T_ACT_ACTION;
-- 查詢物化視圖
SELECT * FROM V_RPT_ACT_ACTION ORDER BY V_RPT_ACT_ACTION.ACTION_VALUE;
-- 刷新物化視圖 刷新時(shí)間間隔。每1天刷新一次,時(shí)間為凌晨10點(diǎn)
ALTER MATERIALIZED VIEW V_RPT_ACT_ACTION
REFRESH FORCE ON DEMAND
START WITH SYSDATE NEXT TO_DATE(CONCAT(TO_CHAR(SYSDATE+1,'DD-MM-YYYY'),' 22:00:00'),'DD-MM-YYYY HH24:MI:SS');
-- 使用DBMS_MVIEW.REFRESH 手工刷新,刷新物化視圖,可以放在存儲(chǔ)過程中刷新,存儲(chǔ)過程不用寫EXEC
-- DBMS_MVIEW.REFRESH('V_RPT_ACT_ACTION');
-- EXEC DBMS_MVIEW.REFRESH('V_RPT_ACT_ACTION');
-- EXEC DBMS_REFRESH.REFRESH('V_RPT_ACT_ACTION');
-- 完全刷新
-- EXEC DBMS_MVIEW.REFRESH(LIST => 'V_RPT_ACT_ACTION',METHOD => 'c');
-- EXEC DBMS_MVIEW.REFRESH('V_RPT_ACT_ACTION','C');
--快速刷新
-- 表 "BOEREMS"."T_ACT_ACTION" 不帶實(shí)體化視圖日志
-- EXEC DBMS_MVIEW.REFRESH(LIST => 'V_RPT_ACT_ACTION',METHOD => 'f');
-- EXEC DBMS_MVIEW.REFRESH('V_RPT_ACT_ACTION','F');
SELECT SYS_GUID() FROM DUAL;
-- 查詢物化視圖上次刷新時(shí)間
-- LAST_REFRESH_DATE 上次刷新時(shí)間
SELECT * FROM USER_MVIEWS
WHERE MVIEW_NAME = 'V_RPT_ACT_ACTION';
-- 手動(dòng)刷新物化視圖
BEGIN
DBMS_MVIEW.REFRESH('V_RPT_ACT_ACTION');
END;
CREATE OR REPLACE PROCEDURE USP_RVW_REFRESH_VIEW
AS
BEGIN
-- 刷新物化視圖
DBMS_OUTPUT.PUT_LINE('######');
-- DBMS_MVIEW.REFRESH('V_RPT_ACT_ACTION');
DBMS_MVIEW.REFRESH('V_RPT_OBJECTIVE_QUESTIONS','C');
-- EXECUTE IMMEDIATE 'DROP MATERIALIZED VIEW V_RPT_OBJECTIVE_QUESTIONS';
DBMS_MVIEW.REFRESH('V_RPT_COURSE_STUDENT','C');
DBMS_MVIEW.REFRESH('V_RPT_EXAM_STUDENT','C');
-- CALL DBMS_MVIEW.REFRESH('V_RPT_COURSE_STUDENT ','C');
-- CALL DBMS_MVIEW.REFRESH('V_RPT_EXAM_STUDENT ','C');
DBMS_OUTPUT.PUT_LINE('###### FINISH');
END USP_RVW_REFRESH_VIEW;