1. 完全刷新
完全刷新的特點是將主表上的查詢結(jié)果全部寫入和物化視圖同名的基表中。當(dāng)再次刷新時,先清空基表中的所有數(shù)據(jù),再加載最新執(zhí)行的查詢結(jié)果。
使用關(guān)鍵字refresh complete創(chuàng)建完全刷新物化視圖
create materialized view mvc_costs
refresh complete on demand
as select promo_id,sum(unit_cost) cost from costs group by promo_id;
手工執(zhí)行完全刷新命令,完全刷新的字母為C
exec dbms_mview.refresh('MVC_COSTS','C');
如果創(chuàng)建的物化視圖視圖中包含大量數(shù)據(jù),可以使用關(guān)鍵字build deferred不加載數(shù)據(jù),等數(shù)據(jù)庫不忙的時候在手工執(zhí)行完全刷新的方式。
create materialized view mvn_costs
tablespace users
build deferred
refresh complete on demand
as select promo_id,sum(unit_cost) cost from costs group by promo_id;
2. 快速刷新
快速刷新也可以理解為增量刷新。增量數(shù)據(jù)由物化視圖日志來管理。物化視圖創(chuàng)建成功后,查詢結(jié)果已經(jīng)保存在物化視圖的同名基表中。當(dāng)主表產(chǎn)生DML操作時視圖日志會將其保存到增量基表中,等到執(zhí)行快速刷新時將這部分?jǐn)?shù)據(jù)同步到物化視圖基表中,并清除自身的數(shù)據(jù)。
快速刷新物化視圖需要創(chuàng)建日志
create materialized view log on costs with rowid,
sequence(promo_id,unit_cost) including new values;
使用關(guān)鍵字refresh fast創(chuàng)建快速刷新的物化視圖
create materialized view mvf_costs
segment creation immediate
refresh fast with rowid on demand
as select promo_id,sum(unit_cost) cost from costs group by promo_id;
手工執(zhí)行完全刷新命令,完全刷新的字母為F
exec dbms_mview.refresh('MVF_COSTS','F');
3. 提交時刷新
刷新是一種觸發(fā)條件,可以手工觸發(fā),也可以自動觸發(fā)。所謂手工觸發(fā)就是執(zhí)行dbms_mview.refresh包來觸發(fā)刷新事件。在應(yīng)用程序中不一定需要人為的執(zhí)行這條命令,而是當(dāng)程序中滿足某些條件后向數(shù)據(jù)庫發(fā)去這個命令來完成刷新。另一種觸發(fā)方式是自動刷新。當(dāng)主表DML操作提交后就觸發(fā)刷新事件,從而達(dá)到主表和物化視圖實時同步的效果。這種方式有些像stream、Oracle GodenGate、或者是DataGuard的邏輯復(fù)制。
提交刷新用起來很酷,但是也有需要注意的地方
1. 主表提交時基表也提交,系統(tǒng)開銷增大。在繁忙的OLTP系統(tǒng)中會影響一部分性能。如果物化視圖更新出錯,主表也無法提交事務(wù)。
2. 主表和物化視圖必須在同一個數(shù)據(jù)庫中
3. 無法在基表上執(zhí)行分布式事務(wù)
4. 不支持含有對象類型或Oracle補充支持類型的物化視圖
下面看看提交時刷新物化視圖的創(chuàng)建方法
create materialized view log on costs with rowid;
create materialized view mvfc_costs
refresh on commit
as select promo_id,sum(unit_cost) cost from costs group by promo_id
查看當(dāng)前物化視圖中的數(shù)據(jù)
select * from mvfc_costs;
PROMO_ID COST
---------- ----------
999 9313900.88
350 242949.08
351 258268
像主表添加2000條數(shù)據(jù)
insert into costs select * from costs where rownum<2001
2000 rows created.
SH@pdb1 > commit;
Commit complete.
再次查看物化視圖數(shù)據(jù)已經(jīng)變化,刷新成功
SH@pdb1 > select * from mvfc_costs;
PROMO_ID COST
---------- ----------
999 9607463.83
350 242949.08
351 258268
4. 從不刷新
看上去像個沒用的東西,但是存在就有存在的道理。當(dāng)我們需要保存一份快照,正好用的這個功能。當(dāng)然通過create table as select的方式也可以實現(xiàn),物化視圖的靈活的地方是可以快照,也可以解除快照變?yōu)榭伤⑿碌奈锘晥D。
來看看例子:
create materialized view mvs_costs
never refresh
as select promo_id,sum(unit_cost) cost from costs group by promo_id
查看視圖描述信息
select mview_name,refresh_method,refresh_mode,build_mode,fast_refreshable
from user_mviews
where mview_name='MVS_COSTS'
MVIEW_NAME REFRESH_ REFRES BUILD_MOD FAST_REFRESHABLE
-------------------- -------- ------ --------- ------------------
MVS_COSTS NEVER NEVER IMMEDIATE DIRLOAD_LIMITEDDML
使用下面的sql語句可以將從不刷新的物化視圖改變?yōu)橥耆⑿路绞?/div>
SH@pdb1 >
alter materialized view mvs_costs
refresh on demand complete;
Materialized view altered.
狀態(tài)從never修改為complete
SH@pdb1 >
select mview_name,refresh_method,refresh_mode,build_mode,fast_refreshable
from user_mviews
where mview_name='MVS_COSTS';
MVIEW_NAME REFRESH_ REFRES BUILD_MOD FAST_REFRESHABLE
-------------------- -------- ------ --------- ------------------
MVS_COSTS COMPLETE DEMAND IMMEDIATE DIRLOAD_LIMITEDDML
橫向?qū)Ρ雀鞣N物化視圖的刷新方式會發(fā)現(xiàn)有些先進(jìn)、有些落后。其實不是這樣的,每個功能都有適合它的使用場景。最適合的才是最好的。
網(wǎng)頁標(biāo)題:12c物化視圖-刷新方式的對比
標(biāo)題來源:
http://weahome.cn/article/jsppss.html