物化视图的使用(二)

1.1.1.1.1 开启查询重写

从分析结果来看,SALES_MVTRUESTED模式下已经过时。

最简单的方法是刷新sales_mv物化视图。但这种方式不是我们这章节要讲的内容。

在前面章节已经提到过基表数据和物化视图容器表数据不一致,存在脏数据的情况下,如果还需要使用查询重写。则需修改query_rewrite_integritystale_tolerated.

SQL> alter system set query_rewrite_integrity=stale_tolerated;

 

系统已更改。

1.1.1.1.2 分析语句是否可以查询重写

修改完毕后,再次分析查询重写

10G>truncate table rewrite_table;

 

表被截断。

 

10G>execute dbms_mview.Explain_Rewrite(query=>'select upper(p.prod_category) as prod_c

ory,sum(s.amount_sold) as amount_sold from sales s, products p where s.prod_id = p.pro

 group by p.prod_category order by p.prod_category',mv=>'sales_mv',statement_id=>'42')

 

PL/SQL 过程已成功完成。

 

10G>select message from rewrite_table where statement_id='42';

 

MESSAGE

--------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------

--------------------------------------------------------------

QSM-01151: 已重写查询

QSM-01033: 已用实体化视图 SALES_MV 进行重写查询

通过分析表明,该SQL语句支持查询重写。我们再通过语句的执行计划看一下。

SQL> l

  1  select upper(p.prod_category),

  2  sum(s.amount_sold) as amount_sold

  3  from sales s,products p

  4  where s.prod_id=p.prod_id

  5  group by p.prod_category

  6* order by p.prod_category

SQL> /

 

 

执行计划

----------------------------------------------------------

Plan hash value: 3163011340

 

------------------------------------------------------------------------------------------

 

| Id  | Operation                     | Name     | Rows  | Bytes | Cost (%CPU)| Time     |

 

------------------------------------------------------------------------------------------

 

|   0 | SELECT STATEMENT              |          |     5 |   105 |     4  (25)| 00:00:01 |

 

|   1 |  SORT GROUP BY                |          |     5 |   105 |     4  (25)| 00:00:01 |

 

|   2 |   MAT_VIEW REWRITE ACCESS FULL| SALES_MV |    81 |  1701 |     3   (0)| 00:00:01 |

 

------------------------------------------------------------------------------------------

很明显,已经访问了物化视图。

 

1.2 物化视图刷新

1.2.1 手动刷新

1.2.1.1 单线程刷新

1.2.1.1.1 Refresh

SQL> exec dbms_mview.refresh(list=>'SH.SALES_MV');

 

PL/SQL 过程已成功完成。

1.2.1.1.2 refresh_all_mviews

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表示刷新物化视图失败个数。因为要刷新数据库中所有的物化视图,所以在生产环境上不建议使用。这将消耗大量的CPUIO以及影响生产环境的正常使用。

1.2.1.1.3 refresh_dependent

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表示刷新物化视图失败个数。

1.2.1.2 并行刷新

1.2.1.2.1 Refresh

SQL> exec dbms_mview.refresh(list=>'SH.SALES_MV',parallelism => 2);

 

PL/SQL 过程已成功完成。

1.2.1.2.2 refresh_all_mviews

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表示刷新物化视图失败个数。在生产环境上不建议使用。这将消耗大量的CPUIO以及影响生产环境的正常使用。

1.2.1.2.3 refresh_dependent

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表示刷新物化视图失败个数。

1.2.2 自动刷新

1.2.2.1 定时刷新

根据业务的需要,物化视图可以提供定时刷新的功能。其原理是Oraclejob任务调用对应的物化视图名称。根据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物化视图。

1.2.2.2 快速刷新

让物化视图支持快速刷新必须在对应的基表上建立物化视图日志。因为快速刷新需要日志来记录数据增量,这里可以设置基于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 的原因

不能快速刷新的原因少了很多。再看第一个原因。<spa

你可能感兴趣的:(oracle,sql,Access)