物化视图是存储在表中的查询结果。
当优化器找到与与实例化视图关联的查询兼容的用户查询时,数据库可以根据实例化视图重写查询。由于数据库已预先计算了大部分查询结果,因此该技术可提高查询执行效率。
优化器将查找与用户查询兼容的实例化视图,然后使用基于成本的算法来选择实例化视图以重写查询。除非生成的视图的成本比使用生成的视图生成的计划的成本低,否则优化器不会在生成计划时重写查询。
5.5.1关于查询重写和优化器
对查询进行几次检查,以确定它是否适合查询重写。如果查询未通过任何检查,则该查询将应用于明细表而不是具体化视图。就响应时间和处理能力而言,无法重写的代价可能很高。
优化器使用两种不同的方法来确定何时根据实例化视图重写查询。第一种方法将查询的SQL文本与实例化视图定义的SQL文本进行匹配。如果第一种方法失败,那么优化器将使用更通用的方法,在该方法中,查询和实例化视图之间将比较联接,选择,数据列,分组列以及聚合函数。
查询重写对以下类型的SQL语句中的查询和子查询进行操作:
SELECTCREATE TABLE … AS SELECTINSERT INTO … SELECT
此外,她也子查询集合运算UNION,UNION ALL,INTERSECT,和MINUS,和子查询的DML语句,如INSERT,DELETE和UPDATE。
维度,约束和重写完整性级别会影响是否重写查询以使用实例化视图。此外,可以通过REWRITE和NOREWRITE提示以及QUERY_REWRITE_ENABLED会话参数来启用或禁用查询重写。
该DBMS_MVIEW.EXPLAIN_REWRITE过程建议是否可以对查询进行查询重写,如果可以,则使用哪些实例化视图。它还说明了为什么无法重写查询。
5.5.2关于查询重写的初始化参数
查询重写行为由某些数据库初始化参数控制。
表5-1控制查询重写行为的初始化参数
| 初始化参数名称 | 初始化参数值 | 查询重写行为 |
|---|---|---|
OPTIMIZER_MODE | ALL_ROWS(默认)FIRST_ROWS,或FIRST_ROWS_n | 随着 |
QUERY_REWRITE_ENABLED | TRUE(默认)FALSE,或FORCE | 此选项启用优化程序的查询重写功能,从而使优化程序可以利用实例化视图来提高性能。如果设置为 如果设置为 |
QUERY_REWRITE_INTEGRITY | STALE_TOLERATED,TRUSTED或ENFORCED(默认) | 此参数是可选的。但是,如果已设置,则该值必须是在“初始化参数值”列中指定的值之一。 默认情况下,完整性级别设置为 |
相关话题
5.5.3关于查询重写的准确性
查询重写提供了三个级别的重写完整性,这些完整性由初始化参数控制QUERY_REWRITE_INTEGRITY。
您可以为QUERY_REWRITE_INTEGRITY参数设置的值如下:
ENFORCED这是默认模式。优化器仅使用实例化视图中的新鲜数据,并且仅使用基于
ENABLED VALIDATED主键,唯一键或外键约束的关系。TRUSTED在
TRUSTED模式下,优化器相信在尺寸和RELY约束中声明的关系是正确的。在这种模式下,优化器还使用预构建的物化视图或基于视图的物化视图,并且它使用的关系既非强制实施,也非强制实施。它还信任已声明但不信任ENABLED VALIDATED使用维度指定的主键或唯一键约束以及数据关系。此模式提供了更大的查询重写功能,但如果您声明的任何信任关系不正确,也可能导致结果错误的风险。STALE_TOLERATED在
STALE_TOLERATED模式下,优化器使用有效的但包含过时数据的物化视图以及包含新鲜数据的物化视图。此模式提供最大的重写功能,但存在产生不准确结果的风险。
如果将重写完整性设置为最安全的级别,ENFORCED则优化器将仅使用强制的主键约束和引用完整性约束来确保查询的结果与直接访问明细表时的结果相同。
如果将重写完整性设置为以外的其他级别ENFORCED,则在几种情况下,具有重写的输出可能与没有重写的输出不同:
- 物化视图可能与数据的主副本不同步。通常发生这种情况是因为在对实例化视图的一个或多个详细表进行批量加载或DML操作之后,实例化视图刷新过程正在等待处理。在某些数据仓库站点,这种情况是可取的,因为在某些时间间隔刷新某些实例化视图的情况并不罕见。
- 尺寸对象隐含的关系无效。例如,层次结构中某个级别的值不会汇总到一个父值。
- 预建的物化视图表中存储的值可能不正确。
- 由于未强制执行的表或视图约束所定义的不良数据关系可能会导致错误的答案。
您可以QUERY_REWRITE_INTEGRITY在初始化参数文件中或使用ALTER SYSTEMor ALTER SESSION语句进行设置。
5.5.4查询重写示例
此示例说明了使用物化视图进行查询重写的功能。
考虑以下物化视图,cal_month_sales_mv该视图汇总了每个月售出的美元数量:
CREATE MATERIALIZED VIEW cal_month_sales_mv
ENABLE QUERY REWRITE AS
SELECT t.calendar_month_desc, SUM(s.amount_sold) AS dollars
FROM sales s, times t WHERE s.time_id = t.time_id
GROUP BY t.calendar_month_desc;
让我们假设在一个典型的月份中,商店的销售数量约为一百万。因此,此物化汇总视图具有每个月售出的美元金额的预先计算的汇总。
考虑以下查询,该查询询问每个日历月在商店的总销售额:
SELECT t.calendar_month_desc, SUM(s.amount_sold)
FROM sales s, times t WHERE s.time_id = t.time_id
GROUP BY t.calendar_month_desc;
在没有以前的实例化视图和查询重写功能的情况下,Oracle数据库必须sales直接访问该表并计算已售金额的总和以返回结果。这涉及从sales表中读取数百万行,由于磁盘访问,这将不可避免地增加查询响应时间。查询中的联接还会进一步减慢查询响应,因为联接需要在数百万行上进行计算。
在存在物化视图的情况下cal_month_sales_mv,查询重写将透明地将先前的查询重写为以下查询:
SELECT calendar_month, dollars
FROM cal_month_sales_mv;
因为在物化视图中只有几十行cal_month_sales_mv并且没有联接,所以Oracle数据库会立即返回结果。




