您的位置:首页 > 数据库 > Oracle

oracle mv物化视图入门

2010-11-18 11:53 309 查看
物化视图概念类似于discoverer中的summary table。在discoverer的管理端,可以创建不同的summary table。在discoverer进行查询的时候,discoverer首先对查询进行解析,判断查询是否可以使用对应的summary table,如果可以,将会改写查询去查询对应的summary table。

一个例子

通过如下的例子,对比统计数据需求的情况下,使用物化视图会有更快的访问速度。

--创建一张大表
SQL> create table my_all_objects
2 nologging
3 as
4 select * from all_objects
5 union all
6 select * from all_objects
7 union all
8 select * from all_objects
9 /
Table created.

SQL> insert /*+ APPEND */ into my_all_objects
2 select * from my_all_objects;
87945 rows created.

SQL> commit;
Commit complete.

SQL> insert /*+ APPEND */ into my_all_objects
2 select * from my_all_objects;
175890 rows created.

SQL> commit;
Commit complete.

SQL> analyze table my_all_objects compute statistics;
Table analyzed.

SQL> set autotrace traceonly

--通过执行计划可以得知直接对数据进行count计算,需要访问4800数据块
SQL> select owner, count(*) from my_all_objects group by owner;
28 rows selected.

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=989 Card=28 Bytes=14
0)
1 0 SORT (GROUP BY) (Cost=989 Card=28 Bytes=140)
2 1 TABLE ACCESS (FULL) OF 'MY_ALL_OBJECTS' (Cost=471 Card=3
51780 Bytes=1758900)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4804 consistent gets
3004 physical reads
0 redo size
973 bytes sent via SQL*Net to client
510 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
28 rows processed

SQL> set autotrace off

--赋予测试用户query rewrite的权限
SQL> grant query rewrite to scott;
Grant succeeded.

--更改当前session能够query rewrite
SQL> alter session set query_rewrite_enabled=true;
Session altered.

--设定query_rewrite_integrity的值为enforced,有三个置可选,enforced,trusted,STALE_TOLERATED
SQL> alter session set query_rewrite_integrity=enforced;
Session altered.

--创建物化视图
SQL> create materialized view my_all_objects_aggs
2 build immediate
3 refresh on commit
4 enable query rewrite
5 as
6 select owner, count(*)
7 from my_all_objects
8 group by owner
9 /
Materialized view created.

--分析物化视图
SQL> analyze table my_all_objects_aggs compute statistics;
Table analyzed.

--通过执行计划可以得知再进行同样的count计算,只需要访问5个数据块。同时,通过执行路径也可以看到,查询是通过物化视图来完成的。如果业务上对于这种count的计算比较频繁的话,采用物化视图将会节省更多的资源。是一种以空间换取时间的方法。
SQL> set autotrace traceonly
SQL> select owner, count(*)
2 from my_all_objects
3 group by owner;
28 rows selected.

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=28 Bytes=252)
1 0 TABLE ACCESS (FULL) OF 'MY_ALL_OBJECTS_AGGS' (Cost=2 Card= 28 Bytes=252)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
5 consistent gets
0 physical reads
0 redo size
973 bytes sent via SQL*Net to client
510 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
28 rows processed

SQL> set autotrace off

--插入新的纪录
SQL> insert into my_all_objects
2 ( owner, object_name, object_type, object_id )
3 values
4 ( 'New Owner', 'New Name', 'New Type', 1111111 );
1 row created.

SQL> commit;
Commit complete.

SQL> set timing on

--对新纪录的count计算仍然通过物化视图来访问。由于创建物化视图的时候,使用“refresh on commit”语句,表的新增纪录已经刷新到物化视图。
SQL> select owner, count(*)
2 from my_all_objects
3 where owner = 'New Owner'
4 group by owner;

OWNER COUNT(*)
------------------------------ ----------
New Owner 1

Elapsed: 00:00:00.00
SQL> set timing off
SQL>
SQL> set autotrace traceonly
SQL> select owner, count(*)
2 from my_all_objects
3 where owner = 'New Owner'
4 group by owner;

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=9)
1 0 TABLE ACCESS (FULL) OF 'MY_ALL_OBJECTS_AGGS' (Cost=2 Card= 1 Bytes=9)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
442 bytes sent via SQL*Net to client
499 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> set autotrace off

--更改sql,不查询owner字段,只count,发现Oracle足够聪明,即使没有创建物化视图的group语句,还是从物化视图来访问
SQL> set autotrace traceonly
SQL> select count(*)
2 from my_all_objects
3 where owner = 'New Owner';

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=9)
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'MY_ALL_OBJECTS_AGGS' (Cost=2 Card=1 Bytes=9)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
379 bytes sent via SQL*Net to client
499 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL> set autotrace off

对于事物频繁的OLTP系统,尽量少使用物化视图。

设置参数

如下参数可以在数据库层或者Session层设置QUERY_REWRITE_ENABLED和
QUERY_REWRITE_INTEGRITY值。对于QUERY_REWRITE_INTEGRITY有三种值可设:
Enforced:重写只使用数据库中定义的约束和关系。
Trusted:除了数据库中定义的约束和关系,Oracle还会使用其他我们告知Oracle表的某些关系,从而使得数据库能够重写更多的查询。
Stale_Tolerated:最弱的参数,及时物化视图没有同步更新,也会使用物化视图来重写SQL。

查询重写

全文精确匹配
如果查询的语句与存储在数据词典中物化视图字符串精确匹配,那么将会重写查询。这里的精确匹配相对于共享池的比较而言更友好,它会忽略空格,大小写以及其他的一些格式。

部分文本匹配
比较From因子后面的文本,即使Select部分的不匹配。例如:
接前面的例子,物化视图的查询部分的SQL:
Select owner, count(*) from my_all_objects group by owner
如下的查询能够被重写:
Select lower(owner) from my_all_objects group by owner

一般性重写方法
a. 数据满足:查询的数据列在物化视图的查询列中
b. 连接兼容:查询语句中的关联列需要在物化视图的查询列中
c. 分组兼容:查询语句和物化视图都必须有Group by语句,同时物化视图的Group by分组层次应该高于或者等于查询的语句。
d. 聚集兼容:查询语句和物化视图都必须包含聚集语句。如果物化视图包含SUM ()/COUNT () 函数,对于同样列采用AGE () 函数进行计算可以被重写。

确保使用物化视图

如下的例子将会说明在怎样的条件下可以确保采用物化视图重写查询,也会比较QUERY_REWRITE_INTEGRITY值Enforced和Trusted的不同。

--这一部分语句验证如果在数据库中相关约束,而这种约束在定义物化视图
--使用。那么,如果查询即使满足其它被重写的条件(数据满足,关联兼容,
--分组兼容等),也不会被重写。

--创建测试表和物化视图
SQL> create table emp as select * from scott.emp;
Table created.

SQL> create table dept as select * from scott.dept;
Table created.

SQL> alter session set query_rewrite_enabled=true;
Session altered.

--注意这里使用的参数值为enforced,只有查询中的约束和关系在物化视图中存在,才会重写查询。
SQL> alter session set query_rewrite_integrity=enforced;
Session altered.

--创建物化视图,注意这里是“refresh on demand”,需要手动刷新物化视图
SQL> create materialized view emp_dept
2 build immediate
3 refresh on demand
4 enable query rewrite
5 as
6 select dept.deptno, dept.dname, count (*)
7 from emp, dept
8 where emp.deptno = dept.deptno
9 group by dept.deptno, dept.dname
10 /
Materialized view created.

SQL> alter session set optimizer_goal=all_rows;
Session altered.

SQL> set autotrace on

--通过执行计划可以看到这个查询并没有被重写,而是直接访问表“EMP”。这是因为我们并没有定义表emp和dept的之间的主外健之间的关系,这种关系物化视图中使用,例如“emp.deptno = dept.deptno”
SQL> select count(*) from emp;

COUNT(*)
----------
14

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1)
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=82)

Statistics
----------------------------------------------------------
….略

--这一部分语句验证增加相关约束后,查询被重写。

--增加相关的约束和关系
SQL> alter table dept
2 add constraint dept_pk primary key(deptno);
Table altered.

SQL> alter table emp
2 add constraint emp_fk_dept
3 foreign key(deptno) references dept(deptno);
Table altered.

SQL> alter table emp modify deptno not null;
Table altered.

SQL> set autotrace on

--由于增加了约束,Oracle能够重写查询使其通过物化视图“EMP_DEPT”来访问数据。可以查看下面的highlight部分的执行计划。
SQL> select count(*) from emp;

COUNT(*)
----------
14

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1 Bytes=13)
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'EMP_DEPT' (Cost=2 Card=82 Bytes=
1066)

Statistics
----------------------------------------------------------
略….

SQL> set autotrace off

--下面这部分SQL将会在比较query_rewrite_integrity在取值为Enforced和
--Trusted情况下,是否被重写。

--删除上述步骤建立的约束
SQL> alter table emp drop constraint emp_fk_dept;
Table altered.

SQL> alter table dept drop constraint dept_pk;
Table altered.

SQL> alter table emp modify deptno null;
Table altered.

--插入数据
SQL> insert into emp (empno,deptno) values ( 1, 1 );
1 row created.

--手工刷新物化视图,这是因为物化视图创建的时候使用的是“refresh on demand”
SQL> exec dbms_mview.refresh( 'EMP_DEPT' );
PL/SQL procedure successfully completed.

--再次增加约束,但是这次增加了NOVALIDATE因子。这样即使数据不符合约束也能够成功创建。
SQL> alter table dept
2 add constraint dept_pk primary key(deptno)
3 rely enable NOVALIDATE
4 /
Table altered.

SQL> alter table emp
2 add constraint emp_fk_dept
3 foreign key(deptno) references dept(deptno)
4 rely enable NOVALIDATE
5 /
Table altered.

SQL> alter table emp modify deptno not null NOVALIDATE;
Table altered.

SQL> set autotrace on

--设置query_rewrite_integrity值为enforced
SQL> alter session set query_rewrite_integrity=enforced;
Session altered.

--检查增加约束但数据不满足约束的情况下,如果是query_rewrite_integrity的值为enforcedenforced,那么物化视图不会被利用来重写查询。
SQL> select count(*) from emp;
COUNT(*)
----------
15

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1)
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=164)

Statistics
----------------------------------------------------------
略….

--设置query_rewrite_integrity值为trusted
SQL> alter session set query_rewrite_integrity=trusted;
Session altered.

--检查增加约束但数据不满足约束的情况下,如果是query_rewrite_integrity的值为trusted,那么物化视图将会被利用来重写查询。
SQL> select count(*) from emp;
COUNT(*)
----------
14

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1 Bytes=13)
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'EMP_DEPT' (Cost=2 Card=82 Bytes=
1066)

Statistics
----------------------------------------------------------
略….

Dimension
创建纬度映射不同列之间的父子关系,类似于在discoverer中创建的维度,使得在查询的时候根据需求下钻上卷。在这里可以为Oracle提供更多的信息,从而使得重写查询的可能性增大。非常类似discoverer中的hierarchy的概念。

create dimension sales_dimension
--这一部分定义类似于数据库字段的别名
level cust_id is customer_hierarchy.cust_id
level zip_code is customer_hierarchy.zip_code
level region is customer_hierarchy.region
level day is time_hierarchy.day
level mmyyyy is time_hierarchy.mmyyyy
level qtr_yyyy is time_hierarchy.qtr_yyyy
level yyyy is time_hierarchy.yyyy
--定义其中一个层次结构
hierarchy cust_rollup
(
cust_id child of
zip_code child of
region
)
--定义另外一个层次结构
hierarchy time_rollup
(
day child of
mmyyyy child of
qtr_yyyy child of
yyyy
)
--mmyyyy和mon_yyyy是同义词
attribute mmyyyy
determines mon_yyyy;

DBMS_OLAP
通过DBMS_OLAP,可以完成如下工作:
a. 估算物化视图的大小
b. 验证维度对象是否有效
c. 建议建立起它物化视图,找出需要删除的视图并重命名
d. 评估物化视图的使用状况

转载自:http://itjaj.com/thread-2277-1-6.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: