基于分区表的物化视图快速刷新以及维护
【全文转自:http://blog.csdn.net/zjc0507/article/details/7865283】
从业DBA多年,始终致力于OLTP的实时交易类型的数据库。龙年伊始,接手了阿联酋惠普 deliver给阿曼电信的名为Dragon的系统,该系统是用于反恐的data warehousing和BI分析系统,这才第一次和数据仓库有了接触,区区两个月的时间,也没有什么特别深的体会,只是针对工作中碰到的基于大数据量分区表的物化视图有了更多的理解,在此小结一下。
DBA都知道,物化视图是oracle数据库中较低级的一种数据同步方式,针对早期的8i版本的complete refresh,我以前开过一次trace,发现底层居然采用先delete后insert的低级方式来同步数据。自此,我对物化视图这项技术有些不屑一顾,甚至唯恐避之而不及。但是针对报表统计的分析系统,物化视图通过提前生成实际的物理数据,可以为报表统计提供更加快捷的查询效率,如果能够配合高效的快速刷新模式,它还是一种非常好的解决方案。
阿曼电信的BI系统数据库,核心业务数据是通话详单、短信详单、GPRS详单等数据,由于以上几类话单的数据量非
常大,因此数据需要利用range分区,按照每天一个分区存储在分区表中,这是物化视图的基表,数据在每天都需要通过ETL加载一次。而报表统计需要的数据,是通过物化视图手动增量刷新生成的,同样,在每天的ETL加载完基表之后,也需要对物化视图进行一次增量刷新。在技术层面上来说,需要创建基于分区表的物化视图,每天手动进行一次物化视图的增量刷新,而增量刷新的数据其实就是一个分区的数据。
针对这种情况,我采用了PCT(Partition Change Tracking)快速刷新的物化视图,该项技术从9i版本开始引入,也是本篇文章介绍的第一个物化视图技术。
一、PCT(Partition Change Tracking)快速增量刷新物化视图
在进行PCT快速增量刷新时,建立的是分区级别的刷新粒度,而不是和整个表建立联系判断哪些记录需要增量刷新,因此缩小了增量刷新的判断范围,同时增加了增量刷新的效率。而且在使用PCT快速增量刷新时,不需要物化视图日志,因此也就减少了维护物化视图日志所带来的额外开销。
为了能够支持PCT快速增量刷新,需要满足以下几个主要条件:
1. 物化视图的基表必须至少有一个是分区表;
2. 分区表必须是range或list分区;
3. 分区键值(Partition Key)必须是只由一个字段组成;
4. 物化视图的SELECT列表中需要包括分区键值字段,如果使用了GROUP BY,则在GROUP BY的列表中也需要包括分区键值字段。
针对阿曼电信的情况, 以上前3个条件都满足了,唯独第4个不行,由于基表是按天进行分区,而物化视图需要使用GROUP BY统计多天的数据,因此无法在物化视图的SELECT和GROUP BY中使用分区键值。在这种情况下,oracle提供了另外一种方式,即分区标记(Partition Marker)来代替分区键值,分区标记是通过DBMS_MVIEW.PMARKER函数来生成的。详细的使用方法如下例所示,其中的红色字体表示分区标记:
CREATE MATERIALIZED VIEW OMANTELBI.MV_T51_GPRS_CELLID_DAYWS REFRESH FAST ON DEMAND WITH ROWID AS select DBMS_MVIEW.PMARKER(rowid), trunc(START_DATE_TIME) as "Date", SERVED_CELL_ID as Cell_ID, sum(DURATION) as Duration_Aggre, sum(DATA_VOLUME_UP_LINK) as Upload_Aggre, sum(DATA_VOLUME_DOWN_LINK) as Download_Aggre from OMANTELBI.T01_GSM_GPRS_EVENT group by DBMS_MVIEW.PMARKER(rowid), trunc(START_DATE_TIME), SERVED_CELL_ID;
以上方法是通过DBMS_MVIEW.PMARKER标记唯一的rowid来帮助物化视图实现PCT快速增量刷新的案例。实际测试表明,PCT快速增量刷新比普通的快速增量刷新的效率更高,而且避免了物化视图日志的额外维护,使得对分区基表进行的ETL数据加载过程也受益匪浅。
由于阿曼电信的这套BI系统还处在试运行阶段,因此对于已经通过ETL加载并且已经刷新到物化视图的数据,常常需要删除掉一天的数据,然后再重新加载和刷新。针对这种情况,我采用了对物化视图进行分区的方法来提高维护的效率,这也是本篇文章介绍的第二种物化视图技术。
二、对物化视图做分区
对物化视图进行分区后,如果需要针对特定的分区进行重新刷新的操作,则可以对分区物化视图执行truncate partition操作,再利用PCT快速增量刷新只刷新truncate掉的分区,其他分区的数据则保持不变,大大提高了对物化视图维护的效率。
对物化视图进行分区,需要利用到物化视图的prebuilt table特性,即先按照分区语法创建物化视图的prebuilt 表,再利用该prebuilt表创建物化视图,详细语法如下例所示:
CREATE TABLE part_sales_tab_mv(time_id, cust_id, sum_dollar_sales, sum_unit_sale) PARALLEL PARTITION BY RANGE (time_id) (PARTITION month1 VALUES LESS THAN (TO_DATE('31-12-2010', 'DD-MM-YYYY')) PCTFREE 0 PCTUSED 99 STORAGE (INITIAL 64k NEXT 16k PCTINCREASE 0) TABLESPACE sf1, PARTITION month2 VALUES LESS THAN (TO_DATE('31-12-2011', 'DD-MM-YYYY')) PCTFREE 0 PCTUSED 99 STORAGE (INITIAL 64k NEXT 16k PCTINCREASE 0) TABLESPACE sf2, PARTITION month3 VALUES LESS THAN (TO_DATE('31-12-2012', 'DD-MM-YYYY')) PCTFREE 0 PCTUSED 99 STORAGE (INITIAL 64k NEXT 16k PCTINCREASE 0) TABLESPACE sf3) AS SELECT s.time_id, s.cust_id, SUM(s.amount_sold) AS sum_dollar_sales, SUM(s.quantity_sold) AS sum_unit_sales FROM sales s GROUP BY s.time_id, s.cust_id;
从语法上看,上面的语句与创建一个分区表的语句没有任何区别,只须留意一下红色字体的表的名称,玄机在下面这个创建物化视图的语句上,物化视图的名称和上面的prebuilt 表的名称必须相同,并且要注意增加ON PREBUILT TABLE关键字:
CREATE MATERIALIZED VIEW part_sales_tab_mvON PREBUILT TABLEENABLE QUERY REWRITE ASSELECT s.time_id, s.cust_id, SUM(s.amount_sold) AS sum_dollar_sales,SUM(s.quantity_sold) AS sum_unit_salesFROM sales s GROUP BY s.time_id, s.cust_id;
以上是对物化视图进行分区的操作案例。我曾试图用指定特定分区的方法进行分区增量刷新,但发现DBMS_MVIEW.REFRESH根本就没有指定分区的参数,因此略感遗憾。我想今后的新版本或许能增加这个功能,使得对分区物化视图的维护更加高效和便捷。
通过对物化视图分区时用到的prebuilt table这个功能,我又无心插柳的搞定了另外一个问题,prebuilt不仅能帮助我们创建分区物化视图,还可以帮助我们对物化视图增加字段或修改字段类型,也是本篇文章介绍的第三个物化视图技术。
三、如何快速修改物化视图的字段
还是这个BI项目,报表开发team的同事提出,在物化视图已经存在大量数据的情况下,想给物化视图增加一个字段,并且把另外一个字段的类型从varchar2修改成number,又不想重新全量刷新物化视图,有什么方法可以实现?
我查了查SQL手册,根本就没有ALTER MATERIALIZED VIEW … MODIFY和ALTER MATERIALIZED VIEW … ADD这样的语句,阿曼电信的数据量很大,drop掉物化视图,再重新创建并且全量刷新会用很长时间,就没有更好的办法了吗?
这时prebuilt table就派上用场了,针对已经存在大量数据的物化视图,修改字段的操作居然可以在几秒以内完成!
在这里需要再强调一下segment的概念,在数据库逻辑存储的概念上讲,物化视图和表一样,都是segment。然而不同的是,我们不能像对表增加字段那样直接给物化视图增加字段。但是我们可以利用它们在存储层相同的特质,利用prebuilt table的功能,采用变通的方法来给物化视图直接增加字段,下面的例子将详细解释。
首先创建一个基表T1:
1
|
Create table T1 (id char (2), amount number);
|
创建prebuilt table,注意表名MV1和打算后续创建的物化视图名称相同:
1
|
Create table MV1 (id char (2), sum number);
|
创建物化视图日志:
1
|
Create materialized view log on T1 with row id including new values ;
|
创建物化视图使用on prebuilt table功能:
1
|
Create materialized view mv1 on prebuilt table refresh fast
|
2
|
As select id, sum (amount) sum from t1 group by id;
|
这时物化视图已成功创建,接下来删掉MV1这个物化视图。
1
|
Drop materialized view MV1;
|
由于我们使用了prebuilt table,因此MV1这个物化视图被drop了之后,在数据字典里MV1这个表也就是MV1这个segment依然存在。这时我们可以使用alter table语句来修改字段类型,或者增加字段:
1
|
Alter table T1 add ( name varchar2(20));
|
这时再执行创建物化视图的语句:
1
|
Create materialized view mv1 on prebuilt table refresh fast
|
2
|
As select id, name , sum (amount) sum from t1 group by id, name ;
|
MV1这个物化视图又被成功创建了,不但成功添加了name字段,而且还包含删除之前所有的数据,因为这个segment根本就是一直存在的。
Prebuilt table实在是个好工具,建议创建物化视图时都使用这种方法,针对大数据量的情况下尤其应该如此。
希望借此文章,能让大家在碰到大数据量的物化视图方案时,能够展开紧锁的眉头,可以有更多的选择。
原帖在此 请点我
基于分区表的物化视图快速刷新以及维护相关推荐
- 物化视图的刷新方式说明
2019独角兽企业重金招聘Python工程师标准>>> 物化视图可以选择三种不同的刷新方式,根据不同的需求,选择不同的刷新方式. Complete刷新:会删除表中的所有记录(如果是单 ...
- 物化视图和视图的最大区别_基于catalyst的物化视图改写引擎的实现
更新日志: 1. 2020/06/16 group by 视图的部分描述错误,已修正. 什么是物化视图 我先用我的话解释一下什么是物化视图.假设我们已经有A,B两张表,现在我创建了一张表C, C是由A ...
- mysql 物化视图 更新_物化视图的快速刷新测试与物化视图日志
前言:一般在创建物化视图的时候,在数据量不大的时候,刷新的方式都是采用完全刷新的.随着系统的使用一些物化视图的源表的数据量在不断的增长,原本采用完全方式几秒就能刷新完成的物化视图,现在需要等待很久的时 ...
- oracle 物化视图 --转
Oracle的物化视图提供了强大的功能,可以用在不同的环境中.在不同的环境中,物化视图的 作用也不相同. 数据仓库中的物化视图主要用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询 ...
- 物化视图实践(1)----实现远程数据同步
概念: 首先澄清:Oracle9i 以前叫做快照(snapshot),自9i开始更名为物化视图(materialized view) . 早先的关键词snapshot被保留并与materialized ...
- 数据库链、物化视图、高级复制方面
数据库链相关内容: JOB自动执行出错,但手工执行正常--浅谈job和database link的一个特点 :描述了匿名数据库链的特点,以及和JOB配合使用时会出现的情况. 通过数据库链执行DDL语句 ...
- oracle雾化试图_Oracle物化视图语法
物化视图概述: Oracle的物化视图提供了强大的功能,可以用在不同的环境中.在不同的环境中,物化视图的作用也不相同.数据仓库中的物化视图主要用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样 ...
- Oracle物化视图与物化视图日志
文章目录 物化视图 物化视图与普通视图的区别 创建一个存放person的表 创建一个存放person的address的表 初始化数据 创建物化视图的语句 1.build [immediate|defe ...
- Oracle开发者性能课第6课(如何创建物化视图)实验
概述 本实验参考DevGym中的实验指南. 创建环境 创建表bricks和索引: exec dbms_random.seed ( 0 ); create table bricks ( brick_id ...
最新文章
- 学习:组件生命周期(1)
- ubuntu中用wine安装office2007
- 怎样基于谷歌地图的Server缓存公布Image Service服务
- java ee规范_测试Java EE 8规范
- 请问运行py文件的时候怎么样可以不让那个黑框一闪...
- (王道408考研操作系统)第三章内存管理-第二节1:虚拟内存管理基本概念
- html拼接html内容,JavaScript如何避免拼接html字符串?
- 20200806:Java拓扑排序实现力扣210课程表Ⅱ
- collins词典第八版mdx_英语词典选择
- SVO深度解析(三)之深度滤波(建图部分)
- MATLAB中SVM(支持向量机)的用法
- std::sort使用
- SQL语句中 NOT IN 子句的“正确打开方式”
- opera官方教程-前台
- bat批处理文件修改注册表
- VS2019下cmake项目:利用ELAS方法计算双目视差
- 黑客帝国「缸中之脑」真的可以,这100万个「活体人脑细胞」5分钟学会打游戏...
- 教妹学 Java:晦涩难懂的泛型
- 大脑皮层由神经组织构成,大脑神经网络结构图片
- 指法练习软件需求说明书
热门文章
- DirectUI,标准界面的又一次挑战!
- spark-sql 指定metastore地址、读取mysql
- List(数组)转Json_js版_Java版_v1.0.0
- 夏季吃5种水果对抗紫外线
- 好玩的话剧 节选之 相亲的密谋
- WEEKDAY函数:
- YOLO&Deepsort的车速&车流量检测系统(源码&部署教程)
- 选择工控,你后悔吗?
- 在xp中tc环境下实现的 销售管理系统(可切换繁体和简体,可设密码,可通过修改代码修改字体颜色)
- 永磁同步电机PMSM直接转矩滞环控制 采用三闭环控制:转速外环采用PI调节器,转矩环和磁链环经过滞环后得到PWM脉冲