Dre*_*mer 2 sql oracle view materialized-views
引自Oracle在线文档
与索引不同,可以使用SELECT语句直接访问实例化视图.但是,建议您尝试避免编写直接引用实例化视图的SQL语句,因为在不影响应用程序的情况下很难更改它们.相反,让查询重写透明地重写您的查询以使用物化视图.
我不太明白direct reference materialized view在上下文中究竟是什么意思,听起来好像SELECT声明没关系,但是不推荐使用外键加入物化视图和订单表/视图,甚至select不建议使用它?为什么?
文档建议您使用物化视图预聚合或预先计算结果,最好让查询重写工作,而不是直接引用查询中的物化视图.如果使用实体化视图从远程数据库复制数据,则无法进行查询重写,您必须直接引用实体化视图.
假设您使用物化视图预先汇总结果,让我们通过一个快速示例.假设您有一个简单的数据仓库,您希望获得该月每种产品的总销售额.直接使用表格,你可能会有类似的东西
SELECT p.product_name,
trunc( s.sales_date, 'MM' ) sales_month,
sum( s.sales_amt ) total_sales
FROM sales_fact s
JOIN product_dim p
ON( s.product_id = p.product_id )
GROUP BY p.product_name, trunc( s.sales_date, 'MM' )
Run Code Online (Sandbox Code Playgroud)
如果要优化它,可以创建多个物化视图,然后依赖查询重写来使用这些物化视图,而不是直接命中表.例如,您可以创建一个物化视图,汇总每天每个产品的销售额
CREATE OR REPLACE MATERIALIZED VIEW sales_by_product_by_day
...
ENABLE QUERY REWRITE
AS
SELECT p.product_name,
trunc( s.sales_date ) sales_day,
sum( s.sales_amt ) total_sales
FROM sales_fact s
JOIN product_dim p
ON( s.product_id = p.product_id )
GROUP BY p.product_name, trunc( s.sales_date )
Run Code Online (Sandbox Code Playgroud)
当然,您可以返回并重写查询以使用sales_by_product_by_day物化视图,即
SELECT product_name,
trunc( sales_day, 'MM' ) sales_month,
sum( total_sales ) total_sales
FROM sales_by_product_by_day
GROUP BY product_name, trunc( sales_day, 'MM' )
Run Code Online (Sandbox Code Playgroud)
但是,通常最好保留查询(引用sales_fact和product_dim视图)并允许查询重写以使用实例化sales_by_product_by_day视图优化查询.从性能角度来看,无论是直接引用实体化视图还是Oracle在查询基表时是否使用查询重写来使用实例化视图都无关紧要.
通过编写对基础表的查询,但是,你让它多的开发人员和DBA更容易在未来调整的一组可用来优化的全套人们正在运行查询的物化视图,而不必经常改写查询.例如,可能会发现您希望物化视图按月按产品汇总.对于这个特定的查询,该物化视图的效率会稍微低一些,但对于许多其他查询来说,这可能会更有效.当然,如果您愿意,可以维护两个物化视图(产生维护许多物化视图的开销).但是,就像索引一样,对于大多数查询而言,使用较少的索引集合而不是大量适合每个查询的索引,通常情况下会更好.
在大多数数据仓库环境中,人们运行的查询集将随着时间的推移而发展,因此您要使用的物化视图集也将随着时间的推移而发展.如果您的查询违反了基表,您可以添加和修改实体化视图并使用查询重写让优化器选择它们并选择要重写的最佳物化视图.但是,如果您的查询引用了特定的物化视图,那么当一个可用的视图可用时,Oracle无法重写另一个物化视图,并且将来更改可用的物化视图集意味着手动重写大量查询.