阿里巴巴数据库操作手册 26-物化视图

V1.0

Revision
Author/Modifier
Comments

No.
Date

1.0
2012/2/15
张中靖
 

 

 

一、 目的

说明物化视图的常用功能和限制条件
二、 适用范围

l 所有线上库
三、 风险评估

l on commit模式创建的物化视图会基表上的分布式事务失败。

l 创建物化视图时查询里使用了*代替基表所有列,后续基表加字段时,物化视图需要重建

l 创建支持快速刷新的物化视图,后续遗忘刷新增量数据,导致物化视图log积压很多

l 多表join的物化视图增量刷新时有重复数据,谨慎使用
四、 操作流程

1. 准备工作

a) 检查用户权限,物化视图的所有者需要CREATE MATERIALIZED VIEW和create table权限,以及基表的查询权限。

如果创建支持on commit刷新的物化视图,需要对基表有ON COMMIT REFRESH权限。

如果创建支持query rewrite的物化视图,需要对基表有QUERY REWRITE权限。

b) 检查用户的表空间配额(quota),物化视图的数据需要独立存储空间。

c) 如果基表跟物化视图不在一个库上,需要创建dblink。

d) 准备物化视图的查询sql,根据需要调整sql结构,保证执行计划正常。

e) 如果创建支持快速刷新的物化视图,需要保证:

l 物化视图不能包含对不重复表达式的引用,如SYSDATE和ROWNUM

l 物化视图不能包含对LONG和LONG RAW数据类型的引用

l 基表必须有主键

l FROM语句列表中的所有表必须建立基于ROWID类型的物化视图日志

l 如果物化视图基表是通过dblink来访问的,查询子句中多表的连接条件必须是主键。

2. 执行过程

a) 创建物化视图日志:(创建非快速刷新的物化视图不需要此步骤)

物化视图的关键点在with子句部分,下面oracle文档上with子句的语法结构:

object id:仅当基表是对象类型时,with 子句可以此项,一般极少使用。

primary key:默认情况下,主键是包含在物化视图日志里,可以不指定此项。

rowid:指定时,物化视图日志里会记录rowid信息。

sequence:指定时,物化视图日志里多一列sequence$$,给每个操作一个SEQUENCE号,从而保证刷新时按照顺序进行刷新。

column:指定哪些列的数据存放在物化视图日志里,注意这些列不能是主键列。

new_value_clause:有两个选项。

默认是excluding new values,即物化视图日志里不记录数据变更时的新值

including new value:即物化视图日志里记录数据变更前后的新旧值,即同

一个主键id会对应两条日志记录。

下面是几个创建物化视图的示例:

CREATE MATERIALIZED VIEW LOG ON customers WITH PRIMARY KEY, ROWID;

CREATE MATERIALIZED VIEW LOG ON sales WITH ROWID, SEQUENCE(amount_sold,

time_id, prod_id)INCLUDNG NEW VALUES;

CREATE MATERIALIZED VIEW LOG ON order_items WITH (product_id);

b) 创建物化视图:

创建物化视图的重点在刷新方式上,刷新方式的语法参照下面:

fast:使用快速刷新,需要先做步骤一,这种刷新方式使用物化视图日志做增量,刷

时间短。

complete:每次都是全量刷新,全量刷新时先truncate物化视图现有数据,重新

从基表生成数据,刷新时间比较长,对应用影响大,一般应用有实时要求的

不能采用这种方式。

force:这种刷新方式会先尝试fast刷新,如果不支持fast,则用complete方式数据,

不指定时,默认是这个。

on commit:物化视图的基表数据发生修改时实时刷新物化视图,这种方式对应用

事务稍有影响,一般不建议使用。

on demand:根据需要刷新,一般采用这个方式,用job或者crontab或者应用程序主动调用dbms_mview.refresh方法来刷新数据。不指定的情况下,默认是这个。

build immediate:创建物化视图的同时做一次全量刷新,一般采用这种方式。不指定时默认是这个。

build deferred:创建物化视图时不生成数据,后续第一次刷新时进行全量刷新。不指定时默认是这个。

enable/disable query rewrite:是否支持查询重写,如果是enable,oracle优化器会对一些sql使用该物化视图进行优化,这样来减少查询时间。

下面是几个创建物化视图的示例:

CREATE MATERIALIZED VIEW sales_mv

BUILD IMMEDIATE

REFRESH FAST ON DEMAND

AS SELECT t.calendar_year, p.prod_id,

SUM(s.amount_sold) AS sum_sales

FROM times t, products p, sales s

WHERE t.time_id = s.time_id AND p.prod_id = s.prod_id

GROUP BY t.calendar_year, p.prod_id;

CREATE MATERIALIZED VIEW sales_by_month_by_state

TABLESPACE example

PARALLEL 4

BUILD IMMEDIATE

REFRESH COMPLETE

ENABLE QUERY REWRITE

AS SELECT t.calendar_month_desc, c.cust_state_province,

SUM(s.amount_sold) AS sum_sales

FROM times t, sales s, customers c

WHERE s.time_id = t.time_id AND s.cust_id = c.cust_id

GROUP BY t.calendar_month_desc, c.cust_state_province;

下面这个是基于dblink的物化视图,查询子句中连接条件不是主键,因此不支持fast

refresh。

CREATE MATERIALIZED VIEW TPCRM_LEADS_INFO

BUILD IMMEDIATE

REFRESH COMPLETE

SELECT o.customer_id as id,

o.gmt_create,

o.gmt_modified,

o.owner_1,

c.country,

c.member_id

FROM caesar.caesar_customer_ggs@crmg c, caesar.caesar_opportunity@crmg o

WHERE c.is_deleted = ‘n’

AND o.is_deleted = ‘n’

AND c.cus_id = o.customer_id;

dbms_mview.explain_mview:如果物化视图创建时报错,可以使用该方法检查报

错原因。下面是个示例,来源于杨铤锟的博客

SQL> alter table fact drop constraint fk_fact_aid;

表已更改。

SQL> alter table dim_a drop primary key;

表已更改。

SQL> create materialized view mv_fact refresh fast on commit as

2 select f.rowid f_rowid, a.rowid a_rowid, b.rowid b_rowid, f.id,

3 a.name a_name, b.name b_name, num

4 from fact f, dim_a a, dim_b b

5 where f.aid = a.id(+)

6 and f.bid = b.id;

from fact f, dim_a a, dim_b b

*

ERROR 位于第 4 行:

ORA-12052: 无法快速刷新实体化视图 YANGTK.MV_FACT

SQL> begin

2 dbms_mview.explain_mview(’select f.rowid f_rowid, a.rowid a_rowid, b.rowid b_rowid, f.id,

3 a.name a_name, b.name b_name, num

4 from fact f, dim_a a, dim_b b

5 where f.aid = a.id(+)

6 and f.bid = b.id’);

7 end;

8 /

PL/SQL 过程已成功完成。

SQL> select msgtxt from mv_capabilities_table where capability_name = ‘REFRESH_FAST_AFTER_INSERT’;

MSGTXT

———————————————————-

在内部表的联接列上没有唯一性约束条件

SQL> alter table dim_a add primary key (id);

表已更改。

SQL> alter table fact add constraint fk_fact_aid foreign key (aid) references dim_a(id);

表已更改。

3. 验证方案:

a) 检查物化视图刷新机制是否正常:

--快速刷新指定的物化视图

execute dbms_mview.refresh(‘物化视图名字‘,‘f’);

--全量刷新指定的物化视图

execute dbms_mview.refresh(‘物化视图名字‘,‘c’);

b) 对物化视图的基表做数据修改,然后使用物化视图的查询子句创建一个临时表。

create table tmp_物化视图名 as 物化视图的查询子句。

然后分别按照上面方法手工刷新物化视图,刷新后核对物化视图和临时表的数据量是否一致。
五、 核心对象风险

物化视图可以用来对核心表进行数据迁移,以及支持核心表的数据抽取。

由于在数据量比较大的情况下,全量刷新耗时比较久,核心表上物化视图尽量使用fast refresh模式。

核心表访问量大,数据变更频繁,其上的物化视图不能使用on commit模式创建。

创建跨dblink的且多表join的物化视图时,如果join条件不是主键,不支持fast refresh,尽量不要在核心表创建这种物化视图。
六、 回退方案

创建物化视图失败时:

如果基表上第一次创建物化视图,使用包dbms_mview.explain_mview检查创建失败原因,如果是物化视图日志不符合要求,删除物化视图日志即可。

如果不确定基表上是否有其他物化视图,检查基表上是否有其他物化视图,如果没有,直接删除物化视日志。

如果存在,需要评估对其他物化视图的影响。

检查基表上依赖的物化视图:

select a.owner, a.name, a.mview_site

from dba_registered_mviews a, dba_base_table_mviews b

where a.mview_id = b.mview_id

and b.master = ‘基表名‘;

七、 历史故障及教训

  1. da shang
    donate-alipay
               donate-weixin weixinpay

发表评论↓↓