1、物化視圖的類型ON DEMAND、ON COMMIT。
二者的差別在於刷新方法的不同,ON DEMAND顧名思義。僅在該物化視圖“須要”被刷新了,才進行刷新(REFRESH),即更新物化視圖,以保證和基表數據的一致性;而ON COMMIT是說,一旦基表有了COMMIT,即事務提交。則立馬刷新,立馬更新物化視圖,使得數據和基表一致。
物化視圖能夠分為下面三種類型:包含聚集的物化視圖。僅僅包含連接的物化視圖;嵌套物化視圖。三種物化視圖的高速刷新的限制條件有非常大差別,而對於其它方面則差別不大。創建物化視圖時能夠指定多種選項,下面對幾種基本的選擇進行簡單說明:
創建方式(Build Methods):包含BUILD IMMEDIATE和BUILD DEFERRED兩種。
BUILD IMMEDIATE是在創建物化視圖的時候就生成數據,而BUILD DEFERRED則在創建時不生成數據。以后依據須要在生成數據。默覺得BUILD IMMEDIATE。
查詢重寫(Query Rewrite):包含ENABLE QUERY REWRITE和DISABLE QUERY REWRITE兩種。分別指出創建的物化視圖是否支持查詢重寫。
查詢重寫是指當對物化視圖的基表進行查詢時,Oracle會自己主動推斷能否通過查詢物化視圖來得到結果,假設能夠,則避免了聚集或連接操作。而直接從已經計算好的物化視圖中讀取數據。
默覺得DISABLE QUERY REWRITE。
在建立物化視圖的時候能夠指定ORDER BY語句,使生成的數據依照一定的順序進行保存。
只是這個語句不會寫入物化視圖的定義中。並且對以后的刷新也無效。
2、ON DEMAND物化視圖物化視圖的創建本身是非常復雜和須要優化參數設置的,特別是針對大型生產數據庫系統而言。但Oracle同意以這樣的最簡單的,類似於普通視圖的方式來做。所以不可避免的會涉及到默認值問題。也就是說Oracle給物化視圖的重要定義參數的默認值處理是我們須要特別注意的。物化視圖的特點:
(1) 物化視圖在某種意義上說就是一個物理表(並且不僅僅是一個物理表),這通過其能夠被user_tables查詢出來,而得到佐證。
(2) 物化視圖也是一種段(segment)。所以其有自己的物理存儲屬性;
(3) 物化視圖會占用數據庫磁盤空間,這點從user_segment的查詢結果。能夠得到佐證。
創建語句:
SQL> create materialized view mv_name as select * from table_name;
默認情況下,假設沒指定刷新方法和刷新模式,則Oracle默覺得FORCE和DEMAND。
物化視圖的數據怎么隨着基表而更新?
Oracle提供了兩種方式,手工刷新和自己主動刷新,默覺得手工刷新。也就是說,通過我們手工的運行某個Oracle提供的系統級存儲過程或包。來保證物化視圖與基表數據一致性。這是最基本的刷新辦法了。
自己主動刷新,事實上也就是Oracle會建立一個job,通過這個job來調用同樣的存儲過程或包。加以實現。
ON DEMAND物化視圖的特性及其和ON COMMIT物化視圖的差別,即前者不刷新(手工或自己主動)就不更新物化視圖,而后者不刷新也會更新物化視圖,——僅僅要基表發生了COMMIT。
創建定時刷新的物化視圖(指定物化視圖每天刷新一次):
SQL> create materialized view mv_name refresh force on demand start with sysdate next sysdate+1;
上述創建的物化視圖每天刷新,可是沒有指定刷新時間,假設要指定刷新時間(比方每天晚上10:00定時刷新一次):
SQL> create materialized view mv_name 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');
3、ON COMMIT物化視圖ON COMMIT物化視圖的創建,和上面創建ON DEMAND的物化視圖差別不大。
因為ON DEMAND是默認的。所以ON COMMIT物化視圖。須要再添加個參數就可以。
須要注意的是,無法在定義時僅指定ON COMMIT。還得附帶個參數才行。創建ON COMMIT物化視圖:
SQL> create materialized view mv_name refresh force on commit as select * from table_name;
備注:實際創建過程中,基表須要有主鍵約束,否則會報錯(ORA-12014)。
4、物化視圖的刷新刷新(Refresh):指當基表發生了DML操作后,物化視圖何時採用哪種方式和基表進行同步。
刷新的模式有兩種:ON DEMAND和ON COMMIT。
刷新的方法有四種:FAST、COMPLETE、FORCE和NEVER。
FAST刷新採用增量刷新,僅僅刷新自上次刷新以后進行的改動。
COMPLETE刷新對整個物化視圖進行全然的刷新。假設選擇FORCE方式,則Oracle在刷新時會去推斷能否夠進行高速刷新。假設能夠則採用FAST方式,否則採用COMPLETE的方式。
NEVER指物化視圖不進行不論什么刷新。
對於已經創建好的物化視圖。能夠改動其刷新方式,比方把物化視圖mv_name的刷新方式改動為每天晚上10點刷新一次:
SQL> alter materialized view mv_name 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');
5、物化視圖日志假設須要進行高速刷新。則須要建立物化視圖日志。物化視圖日志依據不同物化視圖的高速刷新的須要,能夠建立為ROWID或PRIMARY KEY類型的。還能夠選擇是否包含SEQUENCE、INCLUDING NEW VALUES以及指定列的列表。
能夠指明ON PREBUILD TABLE語句將物化視圖建立在一個已經存在的表上。這樣的情況下,物化視圖和表必須同名。當刪除物化視圖時,不會刪除同名的表。這樣的物化視圖的查詢重寫要求參數QUERY_REWRITE_INTEGERITY必須設置為trusted或者stale_tolerated。
6、物化視圖分區並且基於分區的物化視圖能夠支持分區變化跟蹤(PCT)。
具有這樣的特性的物化視圖,當基表進行了分區維護操作后。仍然能夠進行高速刷新操作。對於聚集物化視圖,能夠在GROUP BY列表中使用CUBE或ROLLUP,來建立不同等級的聚集物化視圖。
二、物化視圖與數據遷移Oracle 的物化視圖提供了強大的功能。能夠用於預先計算並保存表連接或聚集等耗時較多的操作的結果,這樣,在運行查詢時。就能夠避免進行這些耗時的操作。而從高速的得到結果。
物化視圖有非常多方面和索引非常類似:使用物化視圖的目的是為了提高查詢性能;物化視圖相應用透明。添加和刪除物化視圖不會影響應用程序中SQL 語句的正確性和有效性。物化視圖須要占用存儲空間;當基表發生變化時,物化視圖也應當刷新。
如怎樣建立在特定的表空間上,這些在其它的物化視圖上面差點兒都沒有不論什么介紹的。主要以我做的一個樣例來操作,假設對物化視圖的基本概念清楚了就比較明確在那里寫特定的表空間存儲了。
1、簡單試驗在master site上創建表和mview log
SQL> create table stu (id varchar2(10) primary key ,name varchar2(20));
Table created.
SQL> create materialized view log on stu;
Materialized view log created.
在mv site上創建mview
SQL> create materialized view stu_mv refresh fast start with sysdate next sysdate+1/1440 with primary key as select * from stu@to_vm9;
Materialized view created.
SQL> select job,log_user,last_date,last_sec,next_date,next_sec,interval,what from user_jobs;
JOB LOG_USER LAST_DATE LAST_SEC NEXT_DATE NEXT_SEC INTERVAL WHAT
--- --------- ----------- --------- ----------- ---------- -------------- -----------------------------------------
21 SEAGULL 2008-2-18 1 14:41:43 2008-2-18 1 14:42:43 sysdate+1/1440 dbms_refresh.refresh('"SEAGULL"."STU_MV"');
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
STU_MV TABLE
在master site上對master table做更新:
SQL> INSERT INTO STU(ID,NAME) VALUES('56','555555555555');
1 row created.
SQL> commit;
等1分鍾后在mv site上檢查
SQL> select * from stu_mv;
ID NAME
---------- --------------------
56 555555555555
2、跨版本號數據遷移利用prebuilt mv實現跨平台,跨版本號數據遷移。該方法的實現原理是對於要遷移的表對象,須要有一個主鍵,用於mv的刷新,對於符合該要求的表,在源表上創建mv日志,再在目標數據庫上創建結構一樣的表。然后在目標表上採用prebuilt方式創建mv。第一次採用全然刷新,之后採用增量刷新,等真正要切換的時候。僅僅須要刷新完增量的日志。刪除mv,保留目標表就可以。基本思路的樣例:
在源庫上創建表和mview log
SQL> create table big_t1 as select * from dba_objects;
Table created.
SQL> select count(1) from big_t1;
COUNT(1)
----------
6170
SQL> create materialized view log on big_t1;
Materialized view log created.
在目標數據庫上創建與該表一樣的表。並在該表上創建prebuilt mv:
SQL> create table big_t1 as select * from big_t1@to_vm9 where 1=2;
Table created.
SQL> select count(1) from big_t1;
COUNT(1)
----------
0
SQL> create materialized view big_t1 on prebuilt table refresh fast as select * from big_t1@to_vm9;
Materialized view created.
做全然刷新和增量刷新
SQL> exec dbms_mview.refresh('BIG_T1','Complete');
PL/SQL procedure successfully completed.
SQL> select count(1) from big_t1;
COUNT(1)
----------
6170
此時模擬在做全然刷新過程中,源庫的表又發生了變化
SQL> insert into big_t1(object_id,owner) values(99991,'test');
1 row created.
SQL> commit;
Commit complete.
再做增量刷新
SQL> select count(1) from big_t1;
COUNT(1)
----------
6170
SQL> exec dbms_mview.refresh('BIG_T1');
PL/SQL procedure successfully completed.
SQL> select count(1) from big_t1;
COUNT(1)
----------
6171
停機切換,做最后一次刷新。然后刪除源庫的mview log和目標庫的mview:
SQL> exec dbms_mview.refresh('BIG_T1');
PL/SQL procedure successfully completed.
SQL> drop materialized view big_t1;
Materialized view dropped.
SQL> select count(1) from big_t1;
COUNT(1)
----------
6171
這里刪除的mview(big_t1)是prebuilt mv,所以刪除該mview,並不刪除相應的表。假設刪除了mvnew(stu_mv),因為是普通mv,則刪除了該mview,就沒有相應的表了。
SQL> drop materialized view stu_mv;
Materialized view dropped.
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
BIG_T1 TABLE
3、創建存儲的日志空間 SQL> CREATE MATERIALIZED VIEW LOG ON mv_lvy_levytaxbgtdiv
tablespace ZGMV_DATA --日志保存在特定的表空間
WITH ROWID ;
SQL> CREATE MATERIALIZED VIEW LOG ON tb_lvy_levydetaildata
tablespace ZGMV_DATA --日志保存在特定的表空間
WITH ROWID,sequence(LEVYDETAILDATAID);
SQL> CREATE MATERIALIZED VIEW LOG ON tb_lvy_levydata
tablespace ZGMV_DATA --日志保存在特定的表空間
WITH rowid,sequence(LEVYDATAID);
4、然后創建物化視圖SQL> 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'
5、刪除物化視圖日志物化視圖日志經常會因為物化視圖長時間沒有刷新,或者基表的一次批量數據更改而變得非常大。這會影響物化視圖的刷新性能,因此對於這樣的情況須要對物化視圖日志進行處理。減少物化視圖日志表的高水位線。
物化視圖日志會記錄下基表全部的增、刪、改操作,而物化視圖運行完高速刷新操作后,會從物化視圖日志中將本物化視圖刷新過且其它物化視圖所不須要刷新的記錄刪除掉。
假設當中一個物化視圖一直不刷新,那么物化視圖日志就會變得越來越大。
另一種情況。比方表中插入了大量的數據,或者刪除了大量的數據,或者將表中的某一列統一更新為一個值,這樣的操作都會在物化視圖日志中產生大量的記錄。
而物化視圖日志的增大必定影響物化視圖的刷新速度。一方面。物化視圖在刷新的時候要掃描物化視圖日志,另一方面。物化視圖在刷新介紹后,也要清除物化視圖日志中的記錄,仍然要掃描物化視圖日志。因此物化視圖日志的大小直接會影響物化視圖高速刷新的速度。更重要的是,物化視圖日志的高水位一旦增長到一個非常高的位置,即使以后物化視圖日志中記錄非常少,甚至沒有記錄存在,物化視圖在刷新的時候仍然須要較長的時間。
SQL> DROP materialized view log on mv_lvy_levytaxbgtdiv;
SQL> DROP materialized view log on tb_lvy_levydetaildata;
SQL> DROP materialized view log on tb_lvy_levydata;
6、刪除物化視圖SQL> drop materialized view MV_LVY_LEVYDETAILDATA;
基本和對表的操作一致,物化視圖因為是物理真實存在的。故能夠創建索引。創建方式和對普通表創建方式同樣。
三、ORACLE物化視圖總結物化視圖是包含一個查詢結果的數據庫對像,它是遠程數據的的本地副本。或者用來生成基於數據表求和的匯總表。物化視圖存儲基於遠程表的數據,也能夠稱為快照。
物化視圖能夠查詢表,視圖和其它的物化視圖。
主要用在數據倉庫和決策支持系統。
通常情況下,物化視圖被稱為主表(在復制期間)或明細表(在數據倉庫中)。對於復制,物化視圖同意你在本地維護遠程數據的副本,這些副本是僅僅讀的。假設你想改動本地副本,必須用高級復制的功能。
當你想從一個表或視圖中抽取數據時。你能夠用從物化視圖中抽取。
對於數據倉庫,創建的物化視圖通常情況下是聚合視圖,單一表聚合視圖和連接視圖。
物化視圖把他的物理結構存儲在自己的段中。該段能夠被索引和分區。
查詢不必全然匹配用來創建物化視圖的SQL語句,優化程序能夠動態重寫一個與原定義相近的查詢,以便物化視圖用來取代實際的表,這樣的查詢重寫自己主動發生,對用戶是透明的。
1、使用物化視圖前的幾個配置步驟(1) 確定那些語句要創建物化視圖。
(2) 決定是否要保持視圖與基礎表數據同步。
假設不同步,可選擇例如以下三種刷新方式:
COMPLETE:刷新啟動時。先truncate物化視圖。再從基礎表又一次插入填充數據。
FAST:僅僅刷新基礎表上次刷新后改變的數據。
使用視圖的日志數據或ROWID完畢。
FORCE:默認的方式。
先使用FAST,不行就使用COMPLETE方式。
(3) 設置init.ora的參數:
JOB_QUEUE_PROCESSES。必須設置大於 1。
QUERY_REWRITE_ENABLED。設置為TRUE時,同意動態重寫查詢。
QUERY_REWRITE_INTEGRITY,確定訪問物化視圖時數據一致性要遵守的程度。
OPTIMIZER_MODE,必須設置成CBO的某種方式。
使用一個物化視圖,用戶僅僅需在基礎表上擁有權限就可以。
2、創建物化視圖SQL>create materialized view emp_by_district
Tablespace mview_data
Build immediate
Refresh fast
Enable query rewrite
As
Select d.id,count(e.last_name) from distributor dist,district d,employee e
Where e.id = dist.manager_id
And d.id dist.district_id
Group by d.id;
下面是Oracle創建物化視圖時的經常使用語法,各參數的含義例如以下:
1、refresh [fast|complete|force] 視圖刷新的方式
fast: 增量刷新.假設前一次刷新的時間為t1,那么使用fast模式刷新物化視圖時,僅僅向視圖中加入t1到當前時間段內,主表變化過的數據.為了記錄這樣的變化,建立增量刷新物化視圖還須要一個物化視圖日志表。create materialized view log on (主表名)。
complete:全部刷新。相當於又一次運行一次創建視圖的查詢語句。
force: 這是默認的數據刷新方式。當能夠使用fast模式時,數據刷新將採用fast方式;否則使用complete方式。
2、MV數據刷新的時間
on demand:在用戶須要刷新的時候刷新,這里就要求用戶自己動手去刷新數據了(也能夠使用job定時刷新)
on commit:當主表中有數據提交的時候。馬上刷新MV中的數據。
start ……:從指定的時間開始,每隔一段時間(由next指定)就刷新一次;
3、Build immediate一共同擁有三個選項
(1) Build immediate:建立物化視圖,並使用當前命令運行的數據馬上填充視圖數據。
(2) Build deferred:僅僅建立物化視圖,在第一次刷新之間不填充數據。
(3) No prebuilt table。使用事先已存在的,已含有視圖定義中有現有數據的表,而不是建立一個新結構來保存數據。
假設是refresh fast on commit或refresh complete on commit創建的,則在基礎表提交的時候都會得到刷新。啟用或禁用物化視圖。須要有query rewrite或global query rewrite權限。
3、刷新物化視圖自己主動刷新:
(1) 使用commit選項。
(2) 使用dbms_mview安排自己主動刷新時間。
手工刷新:
SQL>execute dbms_mview.refresh(‘EMP_BY_DISTRICT’); --刷新指定的物化視圖
SQL>execute dbms_mview.refresh_defresh_dependent(‘EMPLOYEE’); ――刷新利用了該表的全部物化視圖
SQL>execute dbms_mview.refresh_all_mviews; ――刷新該模式中,自上次刷新以來。未得到刷新的全部物化視圖。
4、禁用物化視圖- 改動init.ora參數的query_rewrite_enabled參數設置成flase。重新啟動實例。
- 使用alter system set query_rewrite_enabled = flase;動態改動。
- 使用alter session set query_rewrite_enabled = flash;改動會話內。
- 使用 norewrite提示。
5、刪除物化視圖SQL>drop materialized view emp_by_district;