物化视图日志 快速刷新实验

//快速刷新与物化视图日志

DROP MATERIALIZED VIEW sales_mv;

CREATE MATERIALIZED VIEW sales_mv

ENABLE QUERY REWRITE

AS

SELECT p.prod_category, c.country_id,

       sum(s.quantity_sold) AS quantity_sold,

       sum(s.amount_sold) AS amount_sold

FROM sales s, customers c, products p

WHERE s.cust_id = c.cust_id

AND s.prod_id = p.prod_id

GROUP BY p.prod_category, c.country_id;  //GROUP BY 列表多的那个字段 去掉了 改回了原来的定义。。

ALTER MATERIALIZED VIEW sales_mv REFRESH FAST ON DEMAND;

此时会报 ora-23413 ,因为没有物化视图日子。。MV LOG

 

 2 完全刷新(REFRESH COMPLETE):容器表的所有内容都会被删除,并且所有的数据都会从基础表重新加载只有在相当一部分数据被修改后才去使用这种方式。

 1 快速刷新(REFRESH FAST):容器表中的内容会被重用,只有被修改的数据才会被同步到容器表。 如果基础表上只有少量数据被变更,就应该使用这种方法。效率高,但是限制大。

 3 强制刷新(REFRESH FORCE):当强制刷新时,最初,会尝试使用快速刷新。如果它无法工作,就执行一次完全刷新。

 

#为了激活快速刷新,必须在每个基础表上都创建一个物化视图日志(materialized view log)MV LOG是快速刷新的基本条件 没有它 就无从谈快速刷新了

创建mv log

CREATE MATERIALIZED VIEW LOG ON sales WITH ROWID;

CREATE MATERIALIZED VIEW LOG ON customers WITH ROWID;

CREATE MATERIALIZED VIEW LOG ON products WITH ROWID;

 

在MV的每张基表上都建立 物化视图日志 ,要满足快速刷新,则物化视图的每个基表都必须创建物化视图日志 

 

SELECT master, log_table FROM user_mview_logs

WHERE master IN ('SALES', 'CUSTOMERS', 'PRODUCTS')

AND log_owner = 'SH';

desc mlog$_sales

 

但是如此初级的一个物化视图日志(WITH ROWID)还不足以支持快速刷新,还需要进行一些附加的处理 

具体还需要的要求可以使用包dbms_mview里的存储过程explain_mview来查找 

 

TRUNCATE TABLE mv_capabilities_table; 

execute dbms_mview.explain_mview(mv => 'sales_mv', stmt_id => '42'); 

col MSGTXT for a50

SELECT capability_name, possible, msgtxt, related_text

FROM mv_capabilities_table

WHERE statement_id = '42'

AND capability_name LIKE 'REFRESH_FAST_AFTER%'

ORDER BY seq;

//要解决与物化视图日志相关的这些问题,就必须在执行语句CREATE MATERIALIZED VIEW LOG时添加一些选项:

1、如果是由于物化视图日志没有包含所有的必要字段(MV log does not have all necessary columns),则你必须规定物化视图引用的每一个字段都要保存到物化视图日志中 

2、如果是由于物化视图日志必须有新值(MV log must have new values),则必须使用INCLUDING NEW VALUES子句将这些字段加上。通过使用这个选项,物化视图日志将会同时保存这些字段的新值与旧值(默认情况下只会保存旧值) 

3、如果是由于物化视图日志没有包含序列号(MV log does not have sequence),则有必要添加SEQUENCE子句。通过使用这个选项,就会有一个序列值与存储在物化视图日志中的记录关联在一起了 

 

重新定义物化视图日志

DROP MATERIALIZED VIEW LOG ON sales;

DROP MATERIALIZED VIEW LOG ON customers;

DROP MATERIALIZED VIEW LOG ON products; 

CREATE MATERIALIZED VIEW LOG ON sales WITH ROWID, SEQUENCE

(cust_id, prod_id, quantity_sold, amount_sold) INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW LOG ON customers WITH ROWID, SEQUENCE

(cust_id, country_id) INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW LOG ON products WITH ROWID, SEQUENCE

(prod_id, prod_category) INCLUDING NEW VALUES; 

 

TRUNCATE TABLE mv_capabilities_table;

 

execute dbms_mview.explain_mview(mv => 'sales_mv', stmt_id => '42')

SELECT capability_name, possible, msgtxt, related_text

FROM mv_capabilities_table

WHERE statement_id = '42'

AND capability_name LIKE 'REFRESH_FAST_AFTER%'

ORDER BY seq;

//除了物化视图日志以外,我们还得解决物化视图本身的问题 ,要解决物化视图本身的问题,必须在物化视图创建的时候添加几个基于函数count的新字段。 

 

#下面的SQL语句显示了包含新字段的物化视图定义 

drop materialized view sales_mv; 

CREATE MATERIALIZED VIEW sales_mv

REFRESH FORCE ON DEMAND

AS

SELECT p.prod_category, c.country_id,

       sum(s.quantity_sold) AS quantity_sold,

       sum(s.amount_sold) AS amount_sold,

       count(*) AS count_star,

       count(s.quantity_sold) AS count_quantity_sold,

       count(s.amount_sold) AS count_amount_sold

FROM sales s, customers c, products p

WHERE s.cust_id = c.cust_id

AND s.prod_id = p.prod_id

GROUP BY p.prod_category, c.country_id;

 

#MV的定义里 新增了COUNT字段,再分析一遍

truncate table mv_capabilities_table; 

exec dbms_mview.explain_mview(mv => 'sales_mv',stmt_id => '42'); 

SELECT capability_name, possible, msgtxt, related_text

FROM mv_capabilities_table

WHERE statement_id = '42'

AND capability_name LIKE 'REFRESH_FAST_AFTER%'

ORDER BY seq; 

//结果显示在所有情形下物化视图都支持快速刷新了(字段possible总是被设置成Y)

//下面可以通过往两张表中插入记录并执行快速刷新来测试一下快速刷新究竟有多快

 

set timing on

 

INSERT INTO products 

SELECT 619, prod_name, prod_desc, prod_subcategory,  prod_subcategory_id,

       prod_subcategory_desc, prod_category, prod_category_id,

       prod_category_desc, prod_weight_class, prod_unit_of_measure,

       prod_pack_size, supplier_id, prod_status, prod_list_price, 

       prod_min_price, prod_total, prod_total_id, prod_src_id, 

       prod_eff_from, prod_eff_to, prod_valid

FROM products

WHERE prod_id = 136;

 

 

INSERT INTO sales

SELECT 619, cust_id, time_id, channel_id, promo_id, quantity_sold, amount_sold

FROM sales

WHERE prod_id = 136;

Commit

 

execute dbms_mview.refresh(list => 'sh.sales_mv', method => 'f');

DELETE sales WHERE prod_id = 619;

DELETE products WHERE prod_id = 619;

 

COMMIT;

 

SET TIMING ON

execute dbms_mview.refresh(list => 'sh.sales_mv', method => 'f');

//可以把这个快速刷新的时间和完全刷新的时间比对

快速刷新不是通过CBO获取信息的 而是通过MV LOGS

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22907091/viewspace-713564/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/22907091/viewspace-713564/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值