在执行一个查询时,优化器会判定访问物化视图或数据驻留的基础表是否更快一些。如果优化器判定查询物化视图是更好的解决方案,那么优化器会在一个被称为“查询改写”(query rewrite)的过程中改写SQL查询。在这个过程中,不需要对任何SQL或
本文首先介绍了优化器可以执行的查询改写类型。然后,它讨论了帮助确定创建最佳物化视图集的工具,使优化器能够改写多个查询。利用这些工具创建的物化视图在其基础数据发生变化时还可以快速刷新。如果你不知道创建一个物化视图、一个索引或同时创建两者哪种更好,那么在Oracle数据库10g中引入的SQL Access Advisor可以通过分析给定的工作负荷帮助你做出决定。
查询改写类型
可能有许多类型的查询改写;当物化视图的定义查询与查询的文本完全匹配时,就发生最简单和最显著类型的查询改写。但是,当相同物化视图可用于相应多个查询时,就可以实现查询改写的最大好处。现在,我们将举例说明一些Oracle优化器使用的规则,以确定它是否将使用物化视图来响应。
对于本文中的示例,可以考虑将一个星形模式中的PURCHASES表看作事实表(fact table),其范围由time_key划分。维度表(dimension table)--TIME、PRODUCT和CUSTOMERS--包含主键 time_key、product_id和cust_id。在PURCHASES表中有引用各个维度表的外键约束。
考虑一下清单 1中所创建的物化视图,该视图按月按product_id计算销售总额和销售总次数。注意:对于用于查询改写的物化视图,必须有ENABLE QUERY REWRITE子句。还有,初始化参数QUERY_REWRITE_ENABLED必须被设置为TRUE。
代码清单 1:创建月销售物化视图
| 以下是引用片段: CREATE MATERIALIZED VIEW monthly_sales_mv ENABLE QUERY REWRITE AS SELECT t.month, p.product_id, SUM(ps.purchase_price) as sum_of_sales, COUNT (ps.purchase_price) as total_sales FROM time t, product p, purchases ps WHERE t.time_key = ps.time_key AND ps.product_id = p.product_id GROUP BY t.month, p.product_id; |
集合计算
在本文的示例中,我们将说明物化视图的查询并显示由EXPLAIN PLAN得到的执行计划。清单 2中的查询要求按月和按产品的平均采购价格。优化器可以使用物化视图monthly_sales_mv,利用SUM和COUNT集合计算平均采购价格。这个示例说明了一种叫做“集合计算”的技术。
代码清单 2:获得平均(AVG)采购价格
| 以下是引用片段: SELECT t.month, p.product_id, AVG(ps.purchase_price) as avg_sales FROM time t, product p, purchases ps WHERE t.time_key = ps.time_key AND ps.product_id = p.product_id GROUP BY t.month, p.product_id; Id Operation Name ________________________________________________ SELECT STATEMENT MAT_VIEW REWRITE ACCESS FULL MONTHLY_SALES_MV |
Joinback
Joinback技术非常有用,因为它允许当物化视图中没有列时进行查询改写。清单 3中的查询要求按月和按产品类别的销售总额,而该物化视图中并没有product.category列。然而,产品表的主键product_id列则位于物化视图中。因此,优化器可以将物化视图与产品表联接起来以得到产品类别。
代码清单 3:通过joinback获得销售总额
| 以下是引用片段: SELECT t.month, p.category, SUM(ps.purchase_price) as sum_of_sales FROM time t, product p, purchases ps WHERE t.time_key = ps.time_key AND ps.product_id = p.product_id GROUP BY t.month, p.category; Id Operation Name __________________________________________________ 0 SELECT STATEMENT 1 SORT GROUP BY 2 HASH JOIN 3 TABLE ACCESS FULL PRODUCT 4 MAT_VIEW REWRITE ACCESS FULL MONTHLY_SALES_MV |
使用维度进行查询改写
在一个使用维度建模技巧设计的典型数据仓库中,数据中存在着
对于采用可信信息(包括维度)的查询改写,初始化参数QUERY_ REWRITE_INTEGRITY必须被设置为TRUSTED,如下所示:
| 以下是引用片段: ALTER SESSION SET query_rewrite_integrity = TRUSTED; |
用户评论