通过案例学调优之--跨库建立物化视图(Materialized View)


应用环境:

操作系统: RedHat EL55

Oracle: Oracle 10gR2


一、物化视图概述

Oracle的物化视图是包括一个查询结果的数据库对像,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表。物化视图存储基于远程表的数据,也可以称为快照。

物化视图可以用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,而从快速的得到结果。物化视图有很多方面和索引很相似:使用物化视图的目的是为了提高查询性能;物化视图对应用透明,增加和删除物化视图不会影响应用程序中SQL语句的正确性和有效性;物化视图需要占用存储空间;当基表发生变化时,物化视图也应当刷新。

物化视图可以查询表,视图和其它的物化视图。

通常情况下,物化视图被称为主表(在复制期间)或明细表(在数据仓库中)。

对于复制,物化视图允许你在本地维护远程数据的副本,这些副本是只读的。如果你想修改本地副本,必须用高级复制的功能。当你想从一个表或视图中抽取数据时,你可以用从物化视图中抽取。

对于数据仓库,创建的物化视图通常情况下是聚合视图,单一表聚合视图和连接视图。

在复制环境下,创建的物化视图通常情况下主键,rowid和子查询视图。

物化视图由于是物理真实存在的,故可以创建索引。

二、物化视图刷新

物化视图,根据不同的着重点可以有不同的分类:

1)按刷新方式分:FAST/COMPLETE/FORCE

2)按刷新时间的不同:ON DEMAND/ON COMMIT

3)按是否可更新:UPDATABLE/READ ONLY

4)按是否支持查询重写:ENABLE QUERY REWRITE/DISABLEQUERY REWRITE

默认情况下,如果没指定刷新方法和刷新模式,则Oracle默认为FORCE和DEMAND。

注意:设置REFRESH ON COMMIT的物化视图不能访问远端对象。

在建立物化视图的时候可以指定ORDER BY语句,使生成的数据按照一定的顺序进行保存。不过这个语句不会写入物化视图的定义中,而且对以后的刷新也无效。

物化视图有三种刷新方式:COMPLETE、FAST和FORCE。

1)完全刷新(COMPLETE)会删除表中所有的记录(如果是单表刷新,可能会采用TRUNCATE的方式),然后根据物化视图中查询语句的定义重新生成物化视图。

2)快速刷新(FAST)采用增量刷新的机制,只将自上次刷新以后对基表进行的所有操作刷新到物化视图中去。FAST必须创建基于主表的视图日志。

对于增量刷新选项,如果在子查询中存在分析函数,则物化视图不起作用。

3)采用FORCE方式,Oracle会自动判断是否满足快速刷新的条件,如果满足则进行快速刷新,否则进行完全刷新。

Oracle物化视图的快速刷新机制是通过物化视图日志完成的。Oracle通过一个物化视图日志还可以支持多个物化视图的快速刷新。

物化视图日志根据不同物化视图的快速刷新的需要,可以建立为ROWID或PRIMARY KEY类型的。还可以选择是否包括SEQUENCE、INCLUDING NEW VALUES以及指定列的列表。

三、创建物化视图命令

creatematerializedview[view_name]

refresh[fast|complete|force]

[

on[commit|demand]|

startwith(start_time)next(next_time)

]

as

{创建物化视图用的查询语句}

案例分析:


本案例架构

1)在test1库上建立db link

tnsnames.ora:

[oracle@rh7admin]$cattnsnames.ora#tnsnames.oraNetworkConfigurationFile:/u01/app/oracle/product/11.2.0/db_1/network/admin/tnsnames.ora#GeneratedbyOracleconfigurationtools.TEST1=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=rh7.cuug.net)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=test1)))PROD=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=rh7.cuug.net)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=prod)))

在prod库上建立tom用户,并授权15:18:08SYS@prod>createusertomidentifiedbytom;Usercreated.15:18:27SYS@prod>grantconnect,resourcetotom;Grantsucceeded.15:18:49SYS@prod>grantallonscott.emp1totom;Grantsucceeded.在test1库上建立dblink15:12:12SYS@test1>grantcreatedatabaselink,createpublicdatabaselinktotom;Grantsucceeded.15:13:59TOM@test1>createdatabaselinkdb_link_prodconnecttotomidentifiedbytomusing'prod';Databaselinkcreated.测试:15:19:10TOM@test1>select*fromscott.emp1@db_link_prod;EMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO------------------------------------------------------------------7369SMITHCLERK79021980-12-1700:00:00800207499ALLENSALESMAN76981981-02-2000:00:001600300307521WARDSALESMAN76981981-02-2200:00:001250500307566JONESMANAGER78391981-04-0200:00:002975207654MARTINSALESMAN76981981-09-2800:00:0012501400307698BLAKEMANAGER78391981-05-0100:00:002850307782CLARKMANAGER78391981-06-0900:00:002450107788SCOTTANALYST75661987-04-1900:00:003000207839KINGPRESIDENT1981-11-1700:00:005000107844TURNERSALESMAN76981981-09-0800:00:0015000307876ADAMSCLERK77881987-05-2300:00:001100207900JAMESCLERK76981981-12-0300:00:00950307902FORDANALYST75661981-12-0300:00:003000207934MILLERCLERK77821982-01-2300:00:0013001014rowsselected.

2)在prod库的emp1表上建立物化视图日志

15:06:49SCOTT@prod>createtableemp1asselect*fromemp;Tablecreated.15:09:07SCOTT@prod>altertableemp1addconstraintpk_emp1primarykey(empno);Tablealtered.15:09:26SCOTT@prod>creatematerializedviewlogonemp1;Materializedviewlogcreated.

3)在test1上建立物化视图

在prod库上对tom授权15:19:07SYS@prod>grantselectanytabletotom;Grantsucceeded.在test1库上对tom授权15:22:11SYS@test1>grantcreatematerializedviewtotom;Grantsucceeded.TOM@test1>creatematerializedviewmv1_emp1refreshfastondemandasselect*fromscott.emp1@db_link_prod;测试:15:33:15TOM@test1>select*frommv1_emp1;EMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO------------------------------------------------------------------7369SMITHCLERK79021980-12-1700:00:00800207499ALLENSALESMAN76981981-02-2000:00:001600300307521WARDSALESMAN76981981-02-2200:00:001250500307566JONESMANAGER78391981-04-0200:00:002975207654MARTINSALESMAN76981981-09-2800:00:0012501400307698BLAKEMANAGER78391981-05-0100:00:002850307782CLARKMANAGER78391981-06-0900:00:002450107788SCOTTANALYST75661987-04-1900:00:003000207839KINGPRESIDENT1981-11-1700:00:005000107844TURNERSALESMAN76981981-09-0800:00:0015000307876ADAMSCLERK77881987-05-2300:00:001100207900JAMESCLERK76981981-12-0300:00:00950307902FORDANALYST75661981-12-0300:00:003000207934MILLERCLERK77821982-01-2300:00:0013001014rowsselected.

4)测试物化视图数据刷新

在基表上更新数据15:33:10SYS@prod>connscott/tigerConnected.15:35:59SCOTT@prod>select*fromemp1whereempno=7788;EMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO-----------------------------------------------------------------7876ADAMSCLERK778823-MAY-8711002015:36:04SCOTT@prod>updateemp1setdeptno=40whereempno=7788;1rowupdated.15:36:23SCOTT@prod>commit;Commitcomplete.15:36:35SCOTT@prod>select*fromemp1whereempno=7788;EMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO-----------------------------------------------------------------7788SCOTTANALYST756619-APR-87300040在物化视图上查看数据更新15:35:13TOM@test1>select*frommv1_emp1whereempno=7788;EMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO------------------------------------------------------------------7788SCOTTANALYST75661987-04-1900:00:00300020默认物化视图不会自动更新,需手工更新15:38:12TOM@test1>execdbms_mview.refresh('mv1_emp1','fast');PL/SQLproceduresuccessfullycompleted.15:38:41TOM@test1>select*frommv1_emp1whereempno=7788;EMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO------------------------------------------------------------------7788SCOTTANALYST75661987-04-1900:00:00300040

至此,物化视图建立完成 !


5)查看数据和日志更新信息

在test1上查看数据刷新信息15:39:02TOM@test1>selectmview_name,last_refresh_date,stalenessfromuser_mviews;MVIEW_NAMELAST_REFRESH_DATESTALENESS--------------------------------------------------------------------MV1_EMP12014-08-2215:38:41UNDEFINED在prod上查看物化视图日志更新信息15:40:41SCOTT@prod>selectlog_owner,master,log_table,PRIMARY_KEY,LAST_PURGE_DATE,LAST_PURGE_STATUSfromuser_mview_logsLOG_OWNERMASTERLOG_TABLEPRILAST_PURGLAST_PURGE_STATUS---------------------------------------------------------------------SCOTTEMP1MLOG$_EMP1YES22-AUG-140

6)在物化视图上创建索引

15:39:39TOM@test1>CREATEindexmv1_indonmv1_emp1(ename)tablespaceindx;Indexcreated.16:39:15TOM@test1>selectindex_name,index_type,table_name,BLEVEL,leaf_blocksFROMuser_indexes16:39:302whereindex_name='MV1_IND';INDEX_NAMEINDEX_TYPETABLE_NAMEBLEVELLEAF_BLOCKS---------------------------------------------------------------------MV1_INDNORMALMV1_EMP10116:40:02TOM@test1>select*frommv1_emp1whereename='scott';norowsselectedElapsed:00:00:00.02ExecutionPlan----------------------------------------------------------Planhashvalue:720877713-------------------------------------------------------------------------------------------|Id|Operation|Name|Rows|Bytes|Cost(%CPU)|Time|-------------------------------------------------------------------------------------------|0|SELECTSTATEMENT||1|87|1(0)|00:00:01||1|MAT_VIEWACCESSBYINDEXROWID|MV1_EMP1|1|87|1(0)|00:00:01||*2|INDEXRANGESCAN|MV1_IND|1||1(0)|00:00:01|-------------------------------------------------------------------------------------------PredicateInformation(identifiedbyoperationid):---------------------------------------------------2-access("ENAME"='scott')Note------dynamicsamplingusedforthisstatement(level=2)Statistics----------------------------------------------------------310recursivecalls0dbblockgets44consistentgets0physicalreads0redosize695bytessentviaSQL*Nettoclient408bytesreceivedviaSQL*Netfromclient1SQL*Netroundtripsto/fromclient2sorts(memory)0sorts(disk)0rowsprocessed


案例错误信息:

建立物化视图出错

15:31:27 TOM@ test1 >create materialized view mv1_emp1

15:32:36 2 refresh fast on demand

15:32:36 3 as

15:32:36 4 select * from scott.emp1@db_link_prod;

create materialized view mv1_emp1

*

ERROR at line 1:

ORA-12018: following error encountered during code generation for "TOM"."MV1_EMP1"

ORA-00942: table or view does not exist


解决:

在基表所在的库上,进行授权:

15:19:07 SYS@ prod >grant select any table to tom;

Grant succeeded.