1.01^365=37.8 0.99^365=0.03
分类: Oracle
2014-06-25 10:15:45
Oracle的实体化视图提供了强大的功能,可以用在不同的环境中,实体化视图和表一样可以直接进行查询。实体化视图可以基于分区表,实体化视图本身也可以分区。
主要用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,而从快速的得到结果。在数据仓库中,还经常使用查询重写(query rewrite)机制,这样不需要修改原有的查询语句,Oracle会自动选择合适的实体化视图进行查询,完全对应用透明。实体化视图和表一样可以直接进行查询。
实体化视图还用于复制、移动计算,远程同步等方面。
实体化视图有很多方面和索引很相似:使用实体化视图的目的是为了提高查询性能;实体化视图对应用透明,增加和删除实体化视图不会影响应用程序中SQL语句的正确性和有效性;实体化视图需要占用存储空间;当基表发生变化时,实体化视图也应当刷新。
materialized view 同snapshot是同一个概念。但同view是不一样的:
1)物化视图是存储数据的视图,存储了基础表的全部或者一部分数据,主要用作sql语句的优化,查询物化视图比查询表中的数据速度要快;
2)MV是自动刷新或者手动刷新的,View不用刷新;
3) MV也可以直接update,但是不影响base table,对View的update反映到base table上;
4)MV主要用于远程数据访问,mv中的数据需要占用磁盘空间,view中不保存数据
使用语法:
CREATE MATERIALIZED VIEW XX
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的实体化视图。主键实体化视图允许识别实体化视图表而不影响实体化视图增量刷新的可用性
REWRITE 字句
包括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_mv
CLUSTER my_cluster(index_type)
REFRESH FAST ON COMMIT
ENABLE QUERY REWRITE
AS
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;
-------------------------------------------------
一、Create Materialized View BB
Refresh Complete
Start With Sysdate+10/24 Next Trunc(Sysdate,’Day’)+10/24
As Select Sum(Score) Total From AA Group By Class;
说明:该语句建立了一个实体化视图BB,其源数据从表AA获
得。它的刷新模式为完全刷新(Complete),第一次刷新时间为第二
天上午10点,以后在每星期一的上午10点进行完全刷新。
二、
1。如果要创建基表是其它用户表的实体化视图,那么需要给实体化视图的owner赋予以下权限:
grant CREATE ANY MATERIALIZED VIEW to username;
grant SELECT ANY TABLE to username;
如果要创建refresh on commit的视图,那么还需要下面这个权限:
grant ON COMMIT REFRESH to username;
2。创建refresh on commit的语法如下,此类实体化视图在基表的事务commit之后,就会立刻刷新
CREATE MATERIALIZED VIEW MV_T1
REFRESH FAST ON COMMIT WITH PRIMARY KEY AS SELECT * FROM kamus.t1;
3。如果不指定on commit,那么默认是on demand,只有手工调用DBMS_MVIEW包中的刷新过程,实体化视图才会被刷新
4。指定了start with ... next ...选项之后,第一次创建会有作一次完整刷新,然后在指定的时间间隔之后会定时刷新,本例中刷新间隔为1分钟。
语法如下:
CREATE MATERIALIZED VIEW MV_T1
REFRESH FAST START WITH SYSDATE NEXT sysdate+1/24/60 WITH PRIMARY KEY AS SELECT * FROM kamus.t1;
检查USER_REFRESH视图和USER_JOBS视图,我们可以发现start with... next ...语法也就是Oracle自动创建了一个刷新组,这个刷新组的名称跟实体化视图名称相同,并且IMPLICIT_DESTROY属性为Y,表示只要该组中的实体化视图删除该组也自动被删除。同时,创建了一个JOB,JOB中的waht属性是dbms_refresh.refresh('"SCOTT"."MV_T1"');
自然,由于自动刷新是通过JOB完成的
-------------------------------------------------------------------------
drop MATERIALIZED VIEW PRODUCT_OFFER_INSTANCE;
exec dbms_job.remove(2229);
CREATE MATERIALIZED VIEW PRODUCT_OFFER_INSTANCE
REFRESH FAST ON DEMAND
START WITH sysdate NEXT sysdate + 5/(60*24) WITH PRIMARY KEY
AS
SELECT "PRODUCT_OFFER_INSTANCE"."PRODUCT_OFFER_INSTANCE_ID" "PRODUCT_OFFER_INSTANCE_ID","PRODUCT_OFFER_INSTANCE"."CUST_ID" "CUST_ID","PRODUCT_OFFER_INSTANCE"."CUST_AGREEMENT_ID" "CUST_AGREEMENT_ID","PRODUCT_OFFER_INSTANCE"."PRODUCT_OFFER_ID" "PRODUCT_OFFER_ID","PRODUCT_OFFER_INSTANCE"."EFF_DATE" "EFF_DATE","PRODUCT_OFFER_INSTANCE"."STATE" "STATE","PRODUCT_OFFER_INSTANCE"."STATE_DATE" "STATE_DATE","PRODUCT_OFFER_INSTANCE"."EXP_DATE" "EXP_DATE" FROM "NTCOMM"."PRODUCT_OFFER_INSTANCE"@DB_ACCT "PRODUCT_OFFER_INSTANCE";