首页 > 数据库 > 数据库开发技术 > 使用物化视图和查询重写功能
在本教程中,您将了解如何利用强大的物化视图和查询重写功能。
大约 2 个小时
本教程包括下列主题:
| 概述 | ||
| 情景 | ||
| 前提条件 | ||
| 为销售历史模式实施模式更改 | ||
| 启用查询重写 | ||
| Oracle 的查询重写功能 | ||
| 带有 GROUP BY 扩展项的增强的重写功能 | ||
| 使用重写或错误来控制语句的执行 | ||
| 分区与物化视图 | ||
| 使用带有 PMARKER 信息的物化视图 | ||
| 使用查询重写和部分陈旧的物化视图 | ||
| 使用 TUNE_MVIEW 使物化视图快速刷新 | ||
| 重置环境 | ||
| 总结 | ||
将鼠标置于此图标上以加载和查看本教程的所有屏幕截
图。(警告:因为此操作会同时加载所有屏幕截图,所以网速较慢时,响应时间可能会比较长。)
注意:此外,您还可以在下列步骤中将鼠标放在每个单独的图标上,从而仅加载和查看与 该步骤相关的屏幕截图。您可以单击单个屏幕截图将其隐藏。
通过使用概要管理 (Summary Management) 特性,您可以减轻数据库管理员的工作负荷,这是因为您无需再手动创建概要,而且最终用户也不再必须知道已经定义的概要。一旦您创建了一个或多个物化视图 (它们和概要等效),最终用户就可以查询数据库中的表和视图。Oracle 服务器中的查询重写机制自动重写 SQL 查询以使用概要表。这一机制减少了从查询返回结果的响应时间。数据仓库内的物化视图对于最终用户或数据库应用程序来说是透明的。
Oracle 数据库为您提供用于更先进的重写和刷新机制的增强功能,以及全面的顾问与调整框架。这为您的环境带来了更加优化的物化视图,在占用额外空间最小的情况下提 升了性能。
注意:本教程不是物化视图的介绍。它假定读者对物化视图功能有基本了解。如果您需要更多关于某些 主题的背景信息,请参看 Oracle 数据仓库指南。
您将使用 SALES HISTORY (SH) 示例模式创建、修改并分析物化视图和重写功能。此研讨会依赖于在默认安装上对 SH 模式进行的一些小修改。
开始本教程之前,您应该:
| 1. | |
| 2. |
下载 mv.zip 并将其解压缩到您的工作目录 (c:wkdir) 中。 |
在您启动物化视图功能前,需要对现有的 Sales History 模式对象进行一些更改,还必须将一些额外的系统权限授予用户 SH。使用 SQL 文件 modifySH_10gR2.sql 来应用这些更改。
| 1. |
启动一个 SQL*Plus 会话。选择开始 > 程序 > Oracle-OraDB10g_home > Application Development > SQL Plus。 (请注意:本教程假设您拥有 c:wkdir 文件夹。如果没有,则需要创建此文件夹,并将 mv.zip 的内容解压缩到此文件夹中。在执行脚本时,可指定路经。)
|
| 2. |
以 SH 用户的身份登录。输入 SH 作为 User Name,并输入 SH 作为 Password。然后单击 OK。
|
| 3. |
从 SQL*Plus 会话运行 modifySH_10gR2.sql 脚本。 @c:wkdirmodifySH_10gR2.sql 获得的输出的底部应与以下图像匹配。 ![]() |
| 4. |
执行 xrwutl.sql 脚本。 @c:wkdirxrwutl.sql 获得的输出的底部应与以下图像匹配。
|
要启用查询重写,需要满足以下条件:
| 单个物化视图必须有 ENABLE QUERY REWRITE 子句。 | ||
| 必须将 QUERY_REWRITE_ENABLED 初始化参数设置为 TRUE(在 10g 中是默认设置)。或者,您可以将此参数设置为 FORCE,这将停用对重写计划的任何成本评估,并在任何可能的时候重写查询。 | ||
| 重写完整性模式和特定的物化视图状态必须匹配,以启用对这 一特定物化视图的重写。 | ||
在这一部分中,将启用查询重写。首先,需要确保有对数据库实例的基本初始化设置。为 此,请执行下列步骤:
| 1. |
在登录到 SH 模式的 SQL*Plus 会话中,运行 set_rewrite_session.sql, 或将以下 SQL 语句复制到 SQL*Plus 会话中: @c:wkdirset_rewrite_session
您将启用查询重写,并使用“trusted”模 式。这是最常用的完整性级别。在 trusted 模式中,优化程序相信物化视图中的数据是最新的,在维度中声明的关系和 RELY 约束条件是正确的。在这一方式中,优化程序还将使用预先建立的物化视图或基于视图的物化视图,并使用未执行和已经得到执行的关系。在这一模式中,优化程序 还“信任”已经声明但尚未 ENABLED VALIDATED 的主/唯一键约束条件和通过维度指定的数据关系。 有关 query_rewrite_integrity 的级别和 query_rewrite_enabled 的更多详细信息,请参考 Oracle 据仓库指南。
|
Oracle 数据库 10g 提供用于分析现有的和潜在的物化视图的过程。这使您能够充分利用所有强大的物化视图功能。
要分析其潜在物化视图的刷新和重写功能,请执行以下步骤:
| 1. |
在登录到 SH 模式的 SQL*Plus 会话中,运行 create_mv1.sql, 或将以下 SQL 语句复制到 SQL*Plus 会话中: @c:wkdircreate_mv1.sql
这个语句失败并引发下面的错误: ORA-23413: table "SH"."CUSTOMERS" does not have 您可以尝试手动纠正这个错误并尝试再次创建此物化视图。但是,这是一个循环反复而且耗时的过程。而使用带有 dbms_mview package 的 Oracle 数据库 10g 功能,您可以轻松修复这个错误。您马上就会看到这一点。
|
| 2. |
即便这个语句成功,您也不能了解其快速刷新功能的详细信息。通过使用 dbms_mview.explain_mview package,您对潜在物化视图的功能会有更深入的了解,从而能够在其 创建之前解决所有问题。 @c:wkdirexplain_mv1.sql
在输出中,您会看到系统指向 SALES 表上的另外一个缺少的物化视图日志。建议始终在潜在物化视图创建之前,用上述 dbms_mview.explain_mview 包对其进行分析,而非对系统进行反复试验 (trial-and-error)。 除了 CUSTOMERS 和 SALES 上缺少的物化视图日志,系统还检测到您需要向此物化视图添加额外的聚合函数,来为所有类型的 DML 操作全面启用快速刷新功能。 系统建议的聚合函数是:
dbms_mview.explain_mview 包的输出在此显示。您会发现,它不仅包括物化视图的刷新功能,还包括物化视图的重写和分区变化跟踪(Partition-Change- Tracking,PCT)功能我们会在后面讨论这些功能。
|
| 3. |
要纠正这一点,首先创建上面识别出的物化视图日志。 @c:wkdircreate_mv_logs1.sql
这一个在后面会使用。 DROP MATERIALIZED VIEW LOG ON products; CREATE MATERIALIZED VIEW LOG ON products |
| 4. |
再次检查潜在物化视图的功能。 @c:wkdirexplain_mv1a.sql
此潜在物化视图的快速刷新功能已经按期望进行了更改。
|
| 5. |
现在创建物化视图。 @c:wkdircreate_mv1b.sql
|
| 6. |
explain_mview 过程也使用现有的物化视图。 @c:wkdirexplain_mv1b.sql
|
优化程序使用许多不同方法来重写查询。第一个,也是最重要的步骤,是确定查询所请求的全部或部分结果是否可以从 存储在物化视图的预计算结果中获得。
最简单的情况是,存储在物化视图中的结果与查询所请求的结果完全匹配。Oracle 优化程序通过将查询的文本与物化视图定义的文本相比较来作出这种类型的决定。这种方法是最简单的,但符合这种查询重写类型的查询的数量最少。
当文本比较测试失败后,Oracle 优化程序将基于联接、选择、分组、聚合以及抓取的列数据执行一系列通用检查。这是通过将查询的不同子句(如 SELECT、FROM、WHERE、HAVING 或 GROUP BY)与物化视图的不同子句分别进行比较而完成的。
| 使 用部分文本匹配重写 | ||
| 在 预先建立的表上创建物化视图 | ||
| 使 用简单的联回 (Join Back) 重写 | ||
| 分 析重写过程 | ||
| 使 用联回和卷积重写 | ||
| 使 用复杂的联回和卷积重写 | ||
| 在 数据的子集上创建物化视图 | ||
| 使 用多物化视图重写 | ||
| 估 计物化图的大小 | ||
| 分 析重写过程 | ||
| 用 联回和聚合卷积重写 | ||
最简单的重写机制是文本匹配重写。在全文本匹配中,查询的整个文本会与物化视图定义的整个文本(即整个 SELECT 表达式)相比较 — 在文本比较过程中,忽略空白。在全文本匹配失败后,优化程序会尝试进行部分文本匹配。在这种方法中,以查询的 FROM 子句开始的文本会与以物化视图定义的 FROM 子句开始的文本进行比较。
| 1. |
在登录到 SH 模式的 SQL*Plus 会话中,运行 explain_rewrite1.sql, 或将以下 SQL 语句复制到 SQL*Plus 会话中: @c:wkdirexplain_rewrite1.sql
该计划显示,使用部分文本匹配重写机制,通过 cust_sales_mv materialized 视图重写了查询。以 FROM 子句开始,SQL 语句和物化视图是相同的。 在重写查询的同时,以与访问普通表相同的方法对物化视图的访问计划进行了研究,以便可以使用所有现有索引。
|
| 2. | 执行查询。 @c:wkdirdo_rewrite1.sql
这一查询的执行很快就有结果,因为它只访问在 cust_sales_mv 中已经联接和聚合的信息。
|
| 3. |
可以使用 NOREWRITE 提示来实施针对非编写语句的 计划。这使对一个查询是否重写的控制能下至语句级别。 @c:wkdirexplain_norewrite.sql
如果没有查询重写功能,您必须从 SALES 和与 CUSTOMERS 的联接进行完整扫描。 注意:由于时间限制,不运行此查询。
|
在数据仓库环境中,有已经创建好的概要表或聚合表是很普遍的。您无须通过创建新的物化视图来重复此工作。这个解 决方案将改善物化视图的性能,但是,它不能:
| 为所有 SQL 应用程序提供透明查询重写 | ||
| 在一个应用程序中透明地访问在另一个应用程序中定义的物化视图 | ||
| 普遍支持快速并行或快速物化视图刷新 | ||
由于这些限制,而且由于现有的物化视图可能极为巨大且重建起来费用高昂,Oracle 数据库为您提供了将这些已经存在的概要表注册为物化视图的功能,从而避免了上述所有缺陷。您可以用 CREATE MATERIALIZED VIEW ...ON PREBUILT TABLE 语句注册物化视图。注册之后,物化视图可以用于查询重写,由刷新方法之一或二者一起维护。
Oracle 为其现有客户群实现了这一功能,以提供安全的移植路径并保护投资。移植带有“手工制造”的概要表和刷新过程的现有数据仓库环境,可以用单个 DDL 命令来利用重写功能,不会影响任何现有代码。
例如,MyCompany 最近从 Oracle9i 移植到了 Oracle10g,而且确实有这种手动创建的聚合表,在现有的所有数据仓库 系统中 90% 以上也是如此。要将现有的 cust_id_sales_aggr 表注册为物化视图,请执行以下步骤:
| 1. |
在登录到 SH 模式的 SQL*Plus 会话中,运行 create_mv2.sql, 或将以 SQL 语句复制到 SQL*Plus 会话中: @c:wkdircreate_mv2.sql
这个语句相当快。它完全不会触及任何数据。只是创建物化视图的元信息:哪些联接,哪些聚合,涉及到哪些表和列。 对于查询重写的最高级别的数据完整性 (query_rewrite_integrity=ENFORCED) 而言,在预先建立的表上使用物化视图是不可能的,因为对于数据完整性,系统“信任”您是创建者。只要您开始使用 Oracle 的刷新功能,系统就会知晓数据的完整性。但是,在任何情况下,第一次刷新都会是一次完整的刷新。
|
当文本比较测试失败后,Oracle 优化程序将基于联接、选择、分组、聚合以及抓取的列数据执行一系列通用检查。这是通过将查询的不同子句( SELECT、FROM、WHERE、HAVING 或 GROUP BY) 与物化视图的不同子句分别进行比较而完成的。要使查询重写发生,查询不必始终都完全匹配。例如,假定您的物化视图是按 cust_id 分组,而查询按 cust_last_name 分组。使用一种称为联回的方法,仍可以进行查询重写。
下面是联回重写的一个简单实例。cust_sales_mv 物化视图存储 cust_id 联接列,以与 sales 表和 customers 表确定 cust_credit_limit 值相同的方法与 customers 联接。| 1. |
在登录到 SH 模式的 SQL*Plus 会话中,运行 explain_rewrite2.sql, 或将以下 SQL 语句复制到 SQL*Plus 会话中: @c:wkdirexplain_rewrite2.sql
在此计划中,您可以看到,通过使用 cust_id 列(它是物化视图的组成部分,并表示 sales 表与 customers 表之间的主键-外键关系),Oracle 使用了 cust_sales_mv 物化视图并将其联接回 customers 表。此外,查询中所请求的属性 cust_last_name 是一个来自 cust_id 的确定属性,因而系统知道不必在维点上进行额外聚合。它只须将物化视图联回到 customers 表。关于层次结构和确定属性的信息是 customers_dim(用 于 customers 维的 Oracle 维对象)的组成部分。维定义 customers_dim 的重要部分显示如下: LEVEL customer IS (customers.cust_id) 注意:关于维对象的更多信息,请参看 Oracle 数据仓库指南。
|
| 2. |
执行查询。请注意,只计算结果,而且实际上并不输出 (spool out) 所有返回的记录。 @c:wkdirdo_rewrite2.sql
|
| 3. |
用于非重写查询的计划可以通过以下语句显示: @c:wkdirexplain_norewrite2.sql
若不重新查询,则需要处理完整的 sales 事实表与 customers 维表之间的联接。
|
若要了解系统中查询重写的可能候选对象的详细信息,可以使用 dbms_mview.explain_rewrite 过程。要分析之前执行的查询并更深入地了解重写过程,请执行以下步骤:
| 1. |
在登录到 SH 模式的 SQL*Plus 会话中,运行 analyze_rewrite2.sql, 或将以下 SQL 语句复制到 SQL*Plus 会话中: @c:wkdiranalyze_rewrite2.sql
请注意,上面使用的物化视图并不是唯一适用的;基于预先建立的表的 cust_sales_aggr_id 物化视图也可进行重写了。在这种情况下,优化程序会基于成本做出决策。
|
除了物化视图的简单联回(请求相同聚合级的信息),物化视图还可以聚合到一个更高的级别,即所谓的 ROLLUP(卷积)操作。请看以下查询:
| 1. |
在登录到 SH 模式的 SQL*Plus 会话中,运行 explain_rewrite3.sql, 或将以下 SQL 语句复制到 SQL*Plus 会话中: @c:wkdirexplain_rewrite3.sql
在此计划中,您可以看到,通过使用 cust_id 列(它是物化视图的组成部分,并表示 sales 表与 customers 表之间的主键-外键关系),Oracle 使用 cust_sales_mv 物化视图并将其联接回到 customers 表。 但是,可能的联接键列的存在并不一定代表了 检查 customers_dim 维定义: LEVEL customer IS (customers.cust_id) 所请求的 cust_state_province 属性表示州级,这是比用户级(由 cust_id 表示)更高的聚合级。级别和层次代表一种声明方法,用来表示一个表内的 1:n 关系。在这里,它表示在不影响数据完整性的情况下,将所有客户信息汇总到州级的有效性。每个不同的客户值都将获得一个唯一的州值。
|
| 2. |
现在提交查询。其运行速度相当快。 @c:wkdirdo_rewrite3.sql
|
下面的示例演示了查询重写功能的强大能力和灵活性。以下示例不但进行了联回,而且还使用 customers_dim 维中的息在雪花模式中的两个表上进行了联回。为此,执行下列步骤:
| 1. |
在登录到 SH 模式的 SQL*Plus 会话中,运行 explain_rewrite4.sql, 或将以下 SQL 语句复制到 SQL*Plus 会话中: @c:wkdirexplain_rewrite4.sql
优化程序将重写查询以利用 cust_sales_mv 物化视图,将其联回到 customers 并将 customers 联接到 countries 以满足查询。利用与在不需重写的语句级别上强制执行查询相同的方法,可以强制使用特定的物化视图。 必须进行各种数据完整性检查,以保证使用此物化视图的有效性。除了检查丢失或非复制联接外,对维信息的评估在重写过程中也扮演着重要角色。 检查优化程使用什么来重写这个查询。以下是 customers_dim 的维定义摘录。它显示了这个查询的重要部分: LEVEL customer IS (customers.cust_id) Oracle 数据库必须确定,它是否可以基于存储在该物化视图中的信息导出所有被请求的属性。查询中正在请求 countries.country_name 和 customers.cust_state_province,而 该物化视图只包含 cust_id 信息。 根据 customers_dim 维中的信息,Oracle 数据库可以确定:
Oracle 数据库通过所有这些信息,不但将物化视图与 customers 表联接,而且还将 customers 与 countries 联接,以获得查询的结果,并保证查询结果正确。
|
| 2. | 重写的 SQL 语句如下所示: @c:wkdirrewrite_sel.sql |
| 3. | 现在执行该查询。 @c:wkdirdo_rewrite4.sql
|
| 4. |
如果希望无需查询重写即可获得此计划,可以运行 explain_norewrite4.sql, 或将以下 SQL 语句复制到 SQL*Plus 会话中。 @c:wkdirexplain_norewrite4.sql
请注意,在这个计划中未出现物化视图重写。
|
很多时候,只是考虑对大型事实表中的信息子集进行更多的分析。以前,在这种情况下,为了利用物化视图,您需要为 事实表创建一个包含所有信息的物化视图。现在,您可以在物化视图中并入一个谓词条件,以允许 TEXTMATCH 只重写功能。
要在数据子集上创建一个物化视图,并将其创建间和大小与不带谓词的、包含相同联接、聚合以及完整数据集的物化视 图进行比较,请执行以下步骤:
| 1. |
在登录到 SH 模式的 SQL*Plus 会话中,运行 create_mv3.sql, 或将以下 SQL 语句复制到 SQL*Plus 会话中: @c:wkdircreate_mv3.sql
记录下创建物化视图所耗费的时间。
|
| 2. | 现在,创建相同的物化视图,只是其中无需谓词来限制结果集。 @c:wkdircreate_mv3b.sql
这样创建物化视图用了更长的时间,这是由于所有数据都必须被触及、联接、聚合。
|
Oracle 数据库 10g 第 2 版中的新增内容是,为了解决查询,可使用多个物化视图进行查询重写。
| 1. |
创建以下两个物化视图,其中只包含 2001 年 11 月和 12 月的数据 在登录到 SH 模式的 SQL*Plus 会话中,运行 cr_qw_mmv.sql, 或将以下 SQL 语句复制到 SQL*Plus 会话中: @c:wkdircr_qw_mmv.sql CREATE MATERIALIZED VIEW nov_2001
|
| 2. |
现在执行一个查询,获取在 11 月 5 日至 12 月 15 日期间按客户分类的销售额。运行 explain_mmv.sql,或将以下 SQL 语句复制到 SQL*Plus 会话中: @c:wkdirexplain_mmv.sql DELETE FROM plan_table; COMMIT; EXPLAIN PLAN FOR
|