Oracle的實體化視圖提供了強大的功能,能夠用在不一樣的環境中,實體化視圖和表同樣能夠直接進行查詢。實體化視圖能夠基於分區表,實體化視圖自己也能夠分區。sql
主要用於預先計算並保存錶鏈接或彙集等耗時較多的操做的結果,這樣,在執行查詢時,就能夠避免進行這些耗時的操做,而從快速的獲得結果。在數據倉庫中,還常常使用查詢重寫(query rewrite)機制,這樣不須要修改原有的查詢語句,Oracle會自動選擇合適的實體化視圖進行查詢,徹底對應用透明。實體化視圖和表同樣能夠直接進行查詢。post
實體化視圖還用於複製、移動計算,遠程同步等方面。性能
實體化視圖有不少方面和索引很類似:使用實體化視圖的目的是爲了提升查詢性能;實體化視圖對應用透明,增長和刪除實體化視圖不會影響應用程序中SQL語句的正確性和有效性;實體化視圖須要佔用存儲空間;當基表發生變化時,實體化視圖也應當刷新。
materialized view 同snapshot是同一個概念。但同view是不同的:
1)物化視圖是存儲數據的視圖,存儲了基礎表的所有或者一部分數據,主要用做sql語句的優化,查詢物化視圖比查詢表中的數據速度要快;
2)MV是自動刷新或者手動刷新的,View不用刷新;
3) MV也能夠直接update,可是不影響base table,對View的update反映到base table上;
4)MV主要用於遠程數據訪問,mv中的數據須要佔用磁盤空間,view中不保存數據 優化
使用語法:spa
CREATE MATERIALIZED VIEW XXblog
REFRESH [[fast | complete | force]
[on demand | commit]
[start with date]
[next date]
[with {primary key | rowid}]
]索引
[ENABLE | DISABLE] QUERY REWRITE同步
Refresh 刷新子句
描述 當基表發生了DML操做後,實體化視圖什麼時候採用哪一種方式和基表進行同步
取值 FAST 採用增量刷新,只刷新自上次刷新之後進行的修改
COMPLETE 對整個實體化視圖進行徹底的刷新
FORCE(默認) Oracle在刷新時會去判斷是否能夠進行快速刷新,若是能夠則採用Fast方式,不然採用Complete的方式,Force選項是默認選項
ON DEMAND(默認) 實體化視圖在用戶須要的時候進行刷新,能夠手工經過 DBMS_MVIEW.REFRESH等方法來進行刷新,也能夠經過JOB定時進行刷新
ON COMMIT 實體化視圖在對基表的DML操做提交的同時進行刷新
START WITH 第一次刷新時間
NEXT 刷新時間間隔
WITH PRIMARY KEY(默認) 生成主鍵實體化視圖,也就是說實體化視圖是基於表的主鍵,而不是ROWID(對應於ROWID子句)。 爲了生成PRIMARY KEY子句,應該在表上定義主鍵,不然應該用基於ROWID的實體化視圖。主鍵實體化視圖容許識別實體化視圖表而不影響實體化視圖增量刷新的可用性 it
REWRITE 字句table
包括ENABLE QUERY REWRITE和DISABLE QUERY REWRITE兩種。
分別指出建立的實體化視圖是否支持查詢重寫。查詢重寫是指當對實體化視圖的基表進行查詢時,Oracle會自動判斷可否經過查詢實體化視圖來獲得結果,若是能夠,則避免了彙集或鏈接操做,而直接從已經計算好的實體化視圖中讀取數據
默認 DISABLE QUERY REWRITE
例子:
首先建立表
CREATE TABLE my_tables AS
SELECT DBA_TABLES.* FROM DBA_TABLES;
CREATE TABLE my_indexes AS
SELECT DBA_INDEXES.*
FROM DBA_TABLES, DBA_INDEXES
WHERE DBA_TABLES.OWNER = DBA_INDEXES.table_owner
AND DBA_TABLES.TABLE_NAME = DBA_INDEXES.table_name
建立簇
CREATE CLUSTER my_cluster(index_type VARCHAR2 (30))
SIZE 8192 HASHKEYS 5;
建立MV
CREATE MATERIALIZED VIEW my_mvCLUSTER my_cluster(index_type)REFRESH FAST ON COMMITENABLE QUERY REWRITEAS SELECT t.ROWID AS table_rowid, t.owner AS table_owner, t.tablespace_name, i.rowId AS index_rowId, i.index_type FROM my_tables t, my_indexes i WHERE t.owner = i.table_owner AND t.table_name = i.table_name;