一、物化视图的定义与概述
- 概念
- 物化视图是一种包含了查询结果的数据库对象。它可以将一个复杂的查询结果预先计算并存储起来,就像一个物理的数据表一样。在Oracle数据库中,物化视图的数据存储在数据库的存储结构中,并且可以定期或在特定条件下进行刷新,以保证数据的及时性和准确性。
- 作用
- 提高查询性能:对于那些执行频率高、运算复杂的查询,通过创建物化视图,可以避免每次查询都重新执行复杂的计算过程。例如,一个包含多个表连接、聚合函数(如SUM、COUNT、AVG等)的查询,将其结果存储为物化视图后,后续查询直接从物化视图中获取数据,速度会大大提高。
- 数据整合与分发:可以将分布在不同位置或不同表中的数据进行整合,生成一个统一的视图。在分布式数据库环境或者数据仓库环境中,物化视图可以用于汇总和整合来自多个数据源的数据,方便用户进行数据分析和决策。
二、物化视图的创建语法
- 基本语法
CREATE MATERIALIZED VIEW [view_name]
BUILD [IMMEDIATE | DEFERRED]
REFRESH [FAST | COMPLETE | FORCE]
ON [COMMIT | DEMAND]
AS [select_statement];
- 其中,
CREATE MATERIALIZED VIEW
是创建物化视图的关键字,[view_name]
是要创建的物化视图的名称。 BUILD
选项用于指定物化视图的初始构建方式。IMMEDIATE
表示在创建物化视图时立即构建,也就是执行查询语句并将结果存储起来;DEFERRED
表示推迟构建,物化视图在创建时只是定义了结构,数据会在第一次刷新时填充。REFRESH
选项用于指定物化视图的刷新方式。FAST
表示快速刷新,要求物化视图能够基于增量更新来进行刷新,前提是物化视图基于的基础表要有合适的物化视图日志;COMPLETE
表示完全刷新,会重新执行定义物化视图的查询语句,用新的结果替换原来的数据;FORCE
表示让Oracle根据情况自动选择快速刷新或者完全刷新。ON
选项用于指定刷新的时机。COMMIT
表示在基础表的数据提交后立即刷新物化视图;DEMAND
表示需要用户手动或者通过作业调度来触发刷新。AS [select_statement]
部分是定义物化视图内容的查询语句,这个查询语句可以包含复杂的连接、过滤、聚合等操作。
- 示例
- 例如,创建一个简单的物化视图,用于统计每个部门的员工人数。假设存在
employees
表(包含employee_id
、department_id
等字段)和departments
表(包含department_id
、department_name
等字段)。
CREATE MATERIALIZED VIEW employee_count_per_department
BUILD IMMEDIATE
REFRESH COMPLETE
ON DEMAND
AS
SELECT d.department_name, COUNT(e.employee_id) AS employee_count
FROM departments d
JOIN employees e ON d.department_id = e.department_id
GROUP BY d.department_name;
- 在这个示例中,物化视图
employee_count_per_department
在创建时立即构建(BUILD IMMEDIATE
),刷新方式是完全刷新(REFRESH COMPLETE
),并且需要手动触发刷新(ON DEMAND
)。它的内容是通过连接departments
表和employees
表,按照部门名称分组并统计每个部门的员工人数。
三、物化视图的刷新机制
- 完全刷新(COMPLETE)
- 原理:完全刷新会重新执行定义物化视图的查询语句。它会删除物化视图中原有的数据,然后根据新的查询结果重新填充。例如,对于上面的员工人数统计物化视图,如果采用完全刷新,当基础表(
employees
表和departments
表)的数据发生变化时,会重新执行连接和分组统计操作,用新的统计结果替换物化视图中的旧数据。 - 适用场景:当物化视图的查询比较简单,或者数据量不大,或者无法使用快速刷新的条件(如基础表没有合适的物化视图日志)时,可以使用完全刷新。
- 快速刷新(FAST)
- 原理:快速刷新依赖于物化视图日志。物化视图日志是一种存储在基础表中的特殊日志结构,它记录了基础表数据的变化情况(如插入、更新、删除操作)。当物化视图进行快速刷新时,Oracle会根据物化视图日志中的信息,只更新物化视图中受基础表数据变化影响的部分。例如,如果在
employees
表中插入了一个新员工记录,并且物化视图employee_count_per_department
有合适的物化视图日志,那么在快速刷新时,只会更新与该员工所属部门相关的员工人数统计部分,而不是重新执行整个查询。 - 适用场景:当对物化视图的实时性要求较高,并且基础表的数据变化比较频繁时,快速刷新是比较好的选择。但是,要使用快速刷新,需要在基础表上正确地创建和维护物化视图日志。
- 手动刷新和自动刷新
- 手动刷新:当物化视图的刷新模式是
ON DEMAND
时,需要通过特定的SQL语句来手动触发刷新。可以使用DBMS_MVIEW.REFRESH
过程来实现手动刷新。例如:
BEGIN
DBMS_MVIEW.REFRESH('employee_count_per_department');
END;
- 自动刷新:如果希望物化视图在基础表数据提交后自动刷新(
ON COMMIT
),Oracle会在事务提交时检查物化视图是否需要刷新,并根据定义的刷新方式(快速刷新或完全刷新)进行刷新操作。不过,自动刷新可能会对系统性能产生一定的影响,因为每次基础表的提交都可能触发物化视图的刷新。
四、物化视图的维护和管理
- 查看物化视图的信息
- 可以通过查询数据字典视图来获取物化视图的相关信息。例如,
USER_MVIEWS
视图可以显示当前用户拥有的物化视图的定义信息,包括物化视图的名称、查询语句、刷新模式等。
SELECT mview_name, refresh_mode, build_mode
FROM USER_MVIEWS;
USER_MVIEW_REFRESH_TIMES
视图可以显示物化视图的刷新时间等信息,用于监控物化视图的刷新情况。
- 修改物化视图
- 可以使用
ALTER MATERIALIZED VIEW
语句来修改物化视图的属性,如刷新模式、构建模式等。例如,将一个物化视图的刷新模式从COMPLETE
改为FORCE
:
ALTER MATERIALIZED VIEW employee_count_per_department
REFRESH FORCE;
- 删除物化视图
- 使用
DROP MATERIALIZED VIEW
语句来删除物化视图。例如:
DROP MATERIALIZED VIEW employee_count_per_department;
- 删除物化视图时,会同时删除物化视图存储的数据以及相关的索引等对象。