SQL> exec dbms_mview.refresh(list=>'SH.SALES_MV');
PL/SQL 过程已成功完成。
SQL>set serveroutput on;
SQL> declare
2 i number;
3 begin
4 dbms_mview.refresh_all_mviews(number_of_failures=>i);
5 dbms_output.put_line(‘number_of_failures=>’||i);
6 end;
7 /
number_of_failures=>0
删除当前用户下的所有物化视图,除非对应的物化视图被标记为永不刷新。
Number_of_failures表示刷新物化视图失败个数。因为要刷新数据库中所有的物化视图,所以在生产环境上不建议使用。这将消耗大量的CPU及IO以及影响生产环境的正常使用。
SQL> declare
2 i binary_integer;
3 begin
4 dbms_mview.refresh_dependent(number_of_failures => i,list=>'sh.sales_mv');
5 dbms_output.put_line('number_of_failures=>'||i);
6 end;
7 /
number_of_failures=>0
Number_of_failures表示刷新物化视图失败个数。
SQL> exec dbms_mview.refresh(list=>'SH.SALES_MV',parallelism => 2);
PL/SQL 过程已成功完成。
SQL>set serveroutput on;
SQL> declare
2 i number;
3 begin
4 dbms_mview.refresh_all_mviews(number_of_failures=>i,parallelism => 2);
5 dbms_output.put_line(‘number_of_failures=>’||i);
6 end;
7 /
number_of_failures=>0
删除当前用户下的所有物化视图,除非对应的物化视图被标记为永不刷新。
Number_of_failures表示刷新物化视图失败个数。在生产环境上不建议使用。这将消耗大量的CPU及IO以及影响生产环境的正常使用。
SQL> declare
2 i binary_integer;
3 begin
4 dbms_mview.refresh_dependent(number_of_failures => i,list=>'sh.sales_mv', ,parallelism => 2);
5 dbms_output.put_line('number_of_failures=>'||i);
6 end;
7 /
number_of_failures=>0
Number_of_failures表示刷新物化视图失败个数。
根据业务的需要,物化视图可以提供定时刷新的功能。其原理是Oracle的job任务调用对应的物化视图名称。根据Job触发的时间刷新物化视图。
SQL> alter materialized view sales_mv refresh complete on demand
2 start with sysdate next sysdate+to_dsinterval('0 00:10:00');
实体化视图已更改。
每10分钟刷新sales_mv物化视图。
让物化视图支持快速刷新必须在对应的基表上建立物化视图日志。因为快速刷新需要日志来记录数据增量,这里可以设置基于ROWID来将增量同步到容器表。
在三个基表上建立物化视图日志
SQL> create materialized view log on sales with rowid;
实体化视图日志已创建。
SQL> create materialized view log on customers with rowid;
实体化视图日志已创建。
SQL> create materialized view log on products with rowid;
实体化视图日志已创建。
分析是否可以支持快速刷新
在分析前需要导入@?/rdbms/admin/utlxmv.sql.
则会建立
MV_CAPABILITIES_TABLE表。该表用于记录分析日志。
SQL> @?/rdbms/admin/utlxmv.sql
表已创建。
SQL> exec dbms_mview.explain_mview(mv=>'sh.sales_mv',stmt_id=>'42');
PL/SQL 过程已成功完成。
SQL> select capability_name,possible,msgtxt,related_text from mv_capabilities_table
2 where statement_id='42'
3 and capability_name like 'REFRESH_FAST_AFTER%'
4 order by seq;
CAPABILITY_NAME POSSIBLE MSGTXT
RELATED_TEXT
-------------------------------------------------- ---------- ----------------------------
---------------------------------------------------- --------------------
REFRESH_FAST_AFTER_INSERT N 实体化视图日志必须具有新值
SH.PRODUCTS
REFRESH_FAST_AFTER_INSERT N 实体化视图日志不具有某些必需
的列 SH.PRODUCTS
REFRESH_FAST_AFTER_INSERT N 实体化视图日志必须具有新值
SH.CUSTOMERS
REFRESH_FAST_AFTER_INSERT N 实体化视图日志不具有某些必需
的列 SH.CUSTOMERS
REFRESH_FAST_AFTER_INSERT N 实体化视图日志必须具有新值
SH.SALES
REFRESH_FAST_AFTER_INSERT N 实体化视图日志不具有某些必需
的列 SH.SALES
REFRESH_FAST_AFTER_ONETAB_DML N 使用 SUM(expr) 时, 未提供 CO
UNT(expr) AMOUNT_SOLD
REFRESH_FAST_AFTER_ONETAB_DML N 使用 SUM(expr) 时, 未提供 CO
UNT(expr) QUANTITY_SOLD
REFRESH_FAST_AFTER_ONETAB_DML N 查看禁用 REFRESH_FAST_AFTER_
INSERT 的原因
REFRESH_FAST_AFTER_ONETAB_DML N 在选择列表中不存在 COUNT(*)
REFRESH_FAST_AFTER_ONETAB_DML N 使用 SUM(expr) 时, 未提供 CO
UNT(expr)
REFRESH_FAST_AFTER_ANY_DML N mv 日志没有序列号
SH.PRODUCTS
REFRESH_FAST_AFTER_ANY_DML N mv 日志没有序列号
SH.CUSTOMERS
REFRESH_FAST_AFTER_ANY_DML N mv 日志没有序列号
SH.SALES
REFRESH_FAST_AFTER_ANY_DML N 查看禁用 REFRESH_FAST_AFTER_
ONETAB_DML 的原因
已选择15行。
不能快速刷新的原因有很多,我们先看第一个原因。“实体化视图日志必须具有新值”
而目前物化视图日志默认只有老值。所以要设置物化视图日志属性包括新值。
重建物化视图日志之前,先删除它。
SQL> drop materialized view log on sales;
实体化视图日志已删除。
SQL> drop materialized view log on customers;
实体化视图日志已删除。
SQL> drop materialized view log on products;
实体化视图日志已删除。
重建物化视图日志
SQL> create materialized view log on sales with rowid,sequence
2 (cust_id,prod_id,quantity_sold,amount_sold) including new values;
实体化视图日志已创建。
SQL> create materialized view log on customers with rowid,sequence
2 (cust_id,country_id) including new values;
实体化视图日志已创建。
SQL> create materialized view log on products with rowid,sequence
2 (prod_id,prod_category) including new values;
实体化视图日志已创建。
重新分析快速刷新
SQL> exec dbms_mview.refresh(list=>'sh.sales_mv');
PL/SQL 过程已成功完成。
SQL> drop table mv_capabilities_table;
表已删除。
SQL> @?/rdbms/admin/utlxmv.sql
表已创建。
SQL> exec dbms_mview.explain_mview(mv=>'sh.sales_mv',stmt_id=>'42');
PL/SQL 过程已成功完成。
SQL> select capability_name,possible,msgtxt,related_text from mv_capabilities_table
2 where statement_id='42'
3 and capability_name like 'REFRESH_FAST_AFTER%'
4 order by seq;
CAPABILITY_NAME POSSIBLE MSGTXT
RELATED_TEXT
-------------------------------------------------- ---------- ----------------------------
---------------------------------------------------- --------------------
REFRESH_FAST_AFTER_INSERT Y
REFRESH_FAST_AFTER_ONETAB_DML N 使用 SUM(expr) 时, 未提供 CO
UNT(expr) AMOUNT_SOLD
REFRESH_FAST_AFTER_ONETAB_DML N 使用 SUM(expr) 时, 未提供 CO
UNT(expr) QUANTITY_SOLD
REFRESH_FAST_AFTER_ONETAB_DML N 在选择列表中不存在 COUNT(*)
REFRESH_FAST_AFTER_ANY_DML N 查看禁用 REFRESH_FAST_AFTER_
ONETAB_DML 的原因
不能快速刷新的原因少了很多。再看第一个原因。”使用 SUM(expr) 时, 未提供 CO
UNT(expr)”。意思是你在建物化视图时,要把count给加上。
先删除sales_mv.
SQL> drop materialized view sales_mv;
实体化视图已删除。
SQL> create materialized view SALES_MV
2 refresh complete on demand
3 enable query rewrite
4 as
5 select p.prod_category,c.country_id,
6 sum(s.quantity_sold) as quantity_sold,
7 count(s.quantity_sold) as quantity_sold_count,
8 sum(s.amount_sold) as amount_sold,
9 count(s.amount_sold) as amount_sold_count,
10 count(*) as starX
11 from sales s,customers c,products p
12 where s.cust_id=c.cust_id
13 and s.prod_id=p.prod_id
14 group by p.prod_category,c.country_id;
实体化视图已创建。
再分析下
SQL> drop table mv_capabilities_table;
表已删除。
SQL> @?/rdbms/admin/utlxmv.sql
表已创建。
SQL> exec dbms_mview.explain_mview(mv=>'sh.sales_mv',stmt_id=>'42');
PL/SQL 过程已成功完成。
SQL> select capability_name,possible,msgtxt,related_text from mv_capabilities_table
2 where statement_id='42'
3 and capability_name like 'REFRESH_FAST_AFTER%'
4 order by seq;
CAPABILITY_NAME P MSGTXT RELATE
D_TE
------------------------------ - -------------------------------------------------- ------
----
REFRESH_FAST_AFTER_INSERT Y
REFRESH_FAST_AFTER_ONETAB_DML Y
REFRESH_FAST_AFTER_ANY_DML Y
通过上面的分析,sales_mv已经可以支持快速刷新了。
我们做下测试
SQL> exec dbms_mview.refresh(list=>'sh.sales_mv',method=>'f');
PL/SQL 过程已成功完成。
根据测试,比如对100万记录的表,N并行刷新需要的时间。
拿Oracle10g sh用户下的sales表和customers为例
Sales表数据量为918843
Customers数据量为55500
测试环境为IBM ThinkPad X61 Duo CPU T8300 @2.40GHz.内存3G。OS环境为:Win XP Sp3
创建物化视图sales1_mv
10GEN-U