代码改变世界

物化视图创建案例

2019-06-24 14:54  那个,我  阅读(1304)  评论(0编辑  收藏  举报

1. 创建物化视图日志

Examples


1.1 为快速刷新创建物化视图日志

CREATE MATERIALIZED VIEW LOG ON customers
   PCTFREE 5 
   TABLESPACE example 
   STORAGE (INITIAL 10K);

customers 上的物化视图日志仅支持基于主键的快速刷新

如下语句创建包含 ROWID 属性的物化视图日志, 支持更多类型的物化视图快速刷新:

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

customers 上的物化视图日志支持 rowid 物化视图 和物化联结视图. 要支持物化聚合视同, 需要指定 SEQUENCE 和 INCLUDING NEW VALUES子句,参考后续案例。

1.2 指定定期清理物化视图日志

如下语句为 oe.orders 创建物化视图日志. 日志内容每5天清理一次,从创建时间开始。

CREATE MATERIALIZED VIEW LOG ON orders
  PCTFREE 5
  TABLESPACE example
  STORAGE (INITIAL 10K)
  PURGE REPEAT INTERVAL '5' DAY;

1.3 为物化视图日志指定过滤列

如下为sh.sales 创建物化视图日志并在这里被用到 "Creating Materialized Aggregate Views: Example". 它指定物化视图访问的所有列为过滤列。

CREATE MATERIALIZED VIEW LOG ON sales 
   WITH ROWID, SEQUENCE(amount_sold, time_id, prod_id)
   INCLUDING NEW VALUES; 

1.4 为物化视图日志指定连接列

如下物化视图日志记录primary keys 和 product_id, 如下示例的连接列 "Creating a Fast Refreshable Materialized View: Example".

CREATE MATERIALIZED VIEW LOG ON order_items WITH (product_id);

1.5 在物化视图日志中包含新值

CREATE MATERIALIZED VIEW LOG ON product_information 
   WITH ROWID, SEQUENCE (list_price, min_price, category_id), PRIMARY KEY
   INCLUDING NEW VALUES;

你可以创建如下的物化聚合视图来使用product_information 日志:

CREATE MATERIALIZED VIEW products_mv 
   REFRESH FAST ON COMMIT
   AS SELECT SUM(list_price - min_price), category_id
         FROM product_information 
         GROUP BY category_id;

因为物化视图日志同时记录了旧值和新值,所以其上的物化聚合视图支持快速刷新

1.6 为同步刷新创建暂存日志

如下创建暂存日志被命名为 mystage_log 可用于同步刷新

CREATE MATERIALIZED VIEW LOG ON sales
   PCTFREE 5 
   TABLESPACE example 
   STORAGE (INITIAL 10K)
   FOR SYNCHRONOUS REFRESH USING mystage_log;
 
 

2. 创建物化视图

Examples


2.1 创建简单物化视图

CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM hr.employees;

默认情况下,Oracle数据库创建按需刷新的主键物化视图. 如果employees存在物化视图日志, 则可以将 mv1 修改为 fast refresh. 如果不存在该日志, 则只能执行full refresh. Oracle 为 mv1使用默认存储选项. 执行该操作需要的权限是 CREATEMATERIALIZED VIEW 系统权限,和select on hr.employees 权限.

grant CREATE MATERIALIZED VIEW to test;

grant select on hr.employees to test;

2.2 创建子查询物化视图

CREATE MATERIALIZED VIEW foreign_customers
   AS SELECT * FROM sh.customers@remote cu
   WHERE EXISTS
     (SELECT * FROM sh.countries@remote co
      WHERE co.country_id = cu.country_id);

2.3 创建物化聚合视图

以下创建物化聚合视图并指定刷新方法,模式和时间.使用如下物化视图日志 "Creating a Materialized View Log for Fast Refresh: Examples", 

CREATE MATERIALIZED VIEW LOG ON times
   WITH ROWID, SEQUENCE (time_id, calendar_year)
   INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW LOG ON products
   WITH ROWID, SEQUENCE (prod_id)
   INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW sales_mv
   BUILD IMMEDIATE
   REFRESH FAST ON COMMIT
   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;

2.4 创建物化连接视图

如下语句创建物化聚合视图 sales_by_month_by_state. 语句执行成功即会填充数据.默认情况下,后续刷新将通过重新执行实例化视图的定义查询来完成:

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;

2.5 创建预构建的物化视图

如下语句为预创建的汇总表sales_sum_table创建物化聚合视图

CREATE TABLE sales_sum_table
   (month VARCHAR2(8), state VARCHAR2(40), sales NUMBER(10,2));

CREATE MATERIALIZED VIEW sales_sum_table
   ON PREBUILT TABLE WITH REDUCED PRECISION
   ENABLE QUERY REWRITE
   AS SELECT t.calendar_month_desc AS month, 
             c.cust_state_province AS state,
             SUM(s.amount_sold) AS sales
      FROM times t, customers c, sales s
      WHERE s.time_id = t.time_id AND s.cust_id = c.cust_id
      GROUP BY t.calendar_month_desc, c.cust_state_province;

上述案例允许创建的物化视图可以和预创建表具有相同的表名,相同列数,相同列名。 WITH REDUCED PRECISION 允许创建的物化视图和子查询返回结果有不同精度。

2.6 创建主键物化视图

CREATE MATERIALIZED VIEW catalog   
   REFRESH FAST START WITH SYSDATE NEXT SYSDATE + 1/4096 
   WITH PRIMARY KEY 
   AS SELECT * FROM product_information;  

2.7 创建 ROWID 物化视图

CREATE MATERIALIZED VIEW order_data REFRESH WITH ROWID 
   AS SELECT * FROM orders; 

2.8 定期刷新物化视图

CREATE MATERIALIZED VIEW LOG ON employees
   WITH PRIMARY KEY
   INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW emp_data 
   PCTFREE 5 PCTUSED 60 
   TABLESPACE example 
   STORAGE (INITIAL 50K)
   REFRESH FAST NEXT sysdate + 7 
   AS SELECT * FROM employees; 

上述语句不包含 START WITH 参数, 所以oracle 决定第一次执行日期通过使用SYSDATE评估 NEXT value  .因为创建了物化视图日志,所以oracle 每7天执行一次快速刷新, 从物化视图创建后的第七天开始。

2.9 物化视图的自动刷新时间

CREATE MATERIALIZED VIEW all_customers
   PCTFREE 5 PCTUSED 60 
   TABLESPACE example 
   STORAGE (INITIAL 50K) 
   USING INDEX STORAGE (INITIAL 25K)
   REFRESH START WITH ROUND(SYSDATE + 1) + 11/24 
   NEXT NEXT_DAY(TRUNC(SYSDATE), 'MONDAY') + 15/24 
   AS SELECT * FROM sh.customers@remote 
         UNION
      SELECT * FROM sh.customers@local; 

Oracle数据库将于明天上午11:00自动刷新此物化视图,随后每周一下午3:00自动刷新此物化视图。默认刷新方法为FORCE。定义查询包含一个UNION运算符,快速刷新不支持该运算符,因此数据库将自动执行完整的刷新。

前面的语句还为物化视图和数据库用于维护它的索引建立了存储特性。

2.10 创建快速可刷新的物化视图

以下创建了快速可刷新的物化视图,使用了UNION 操作,并且通过where 限制了返回行。order_items 和product_information(案例似乎没用到)的物化视图日志在前面的CREATE MATERIALIZED VIEW LOG部分已经创建,这里还需要对inventories创建物化视图日志
CREATE MATERIALIZED VIEW LOG ON inventories
   WITH (quantity_on_hand);

CREATE MATERIALIZED VIEW warranty_orders REFRESH FAST AS
  SELECT order_id, line_item_id, product_id FROM order_items o
    WHERE EXISTS
    (SELECT * FROM inventories i WHERE o.product_id = i.product_id
      AND i.quantity_on_hand IS NOT NULL)
  UNION
    SELECT order_id, line_item_id, product_id FROM order_items
    WHERE quantity > 5; 

warranty_orders 视图需要物化视图日志定义在order_items (product_id作为join列)和inventories (quantity_on_hand 作为过滤列),参考前面的#为物化视图日志指定过滤列 和#为物化视图日志指定连接列

2.11 创建嵌套物化视图

以下视图以前面创建的物化视图为主表,创建了一个定制化的视图。

CREATE MATERIALIZED VIEW my_warranty_orders
   AS SELECT w.order_id, w.line_item_id, o.order_date
   FROM warranty_orders w, orders o
   WHERE o.order_id = o.order_id
   AND o.sales_rep_id = 165; 

来源: https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/CREATE-MATERIALIZED-VIEW.html#GUID-EE262CA4-01E5-4618-B659-6165D993CA1B