物化视图是什么:
我的理解是:普通视图保存的是一条 SQL,物化视图保存的是这条 SQL 的查询结果—— 结果以物理表的形式落盘,所以它“像一张表”。
简单说:视图是 “查询的快捷方式”,物化视图是 “查询结果的快照”,本质是用空间换时间—— 多占一点磁盘,换高频查询的大幅提速。
物化视图的数据不会自己更新,需要 “刷新” 来和基表同步。刷新方式可以从两个维度理解:
按刷新方法:
按触发时机:
CREATE MATERIALIZED VIEW [模式名.]物化视图名
(
-- 可选:指定列名(不指定则自动继承查询中的列名)
列1, 列2, ...
)
-- ========== 存储选项(物理属性) ==========
[STORAGE (INITIAL 初始大小, NEXT 增长大小, MINEXTENTS 最小区数, ...)]
[USING INDEX STORAGE (索引存储参数)]
[USING INDEX PCTFREE 百分比]
[PARTITION BY 分区方式 (分区列)] -- 支持对物化视图分区
-- ========== 刷新方式(重点) ==========
[REFRESH
{ FAST | COMPLETE | FORCE } -- 刷新方式:快速/完全/强制
[ ON { DEMAND | COMMIT } ] -- 触发时机:按需/提交时
[ START WITH 开始时间 ] -- 首次自动刷新时间
[ NEXT 下次刷新时间表达式 ] -- 刷新间隔
[ WITH { PRIMARY KEY | ROWID } ] -- 刷新依据
]
-- ========== 是否预建表 ==========
[BUILD { IMMEDIATE | DEFERRED }]
-- IMMEDIATE(立即创建数据)/ DEFERRED(只建结构,稍后刷新)
-- ========== 查询语句 ==========
ASSELECT ... FROM ... [GROUP BY ...] [HAVING ...]
以下实验都在测试库 TEST 下完成,基表是订单明细表 ORDER_DETAIL,字段为:ORDER_DATE(下单日期)、ORDER_NO(订单号)、AMOUNT(金额)、QTY(数量)。目标是建一个 “每日订单汇总” 物化视图,每天自动刷新一次。
1、创建物化视图日志表
快速刷新靠物化视图日志(MLOG)记录基表增量,所以先建日志:
CREATE MATERIALIZED VIEW LOG ON TEST.ORDER_DETAIL
STORAGE (INITIAL 1, NEXT 1, MINEXTENTS 1, FILLFACTOR 0)
WITH ROWID, PRIMARY KEY;
2、创建物化视图
– 每天刷新一次:统计每日订单数、总金额、总件数
CREATE MATERIALIZED VIEW TEST.MV_ORDER_DAY_SUMMARY
REFRESH COMPLETE ON DEMAND
START WITH SYSDATE
NEXT SYSDATE + INTERVAL '1' DAY
AS SELECT
ORDER_DATE,
COUNT(*) AS ORDER_COUNT,
SUM(AMOUNT) AS TOTAL_AMOUNT,
SUM(QTY) AS TOTAL_QTY
FROM TEST.ORDER_DETAIL
GROUP BY ORDER_DATE;
3、手动刷新
-- 全量重建
REFRESH MATERIALIZED VIEW TEST.MV_ORDER_DAY_SUMMARY COMPLETE;
-- 增量同步(前提:满足快速刷新约束)
REFRESH MATERIALIZED VIEW TEST.MV_ORDER_DAY_SUMMARY FAST;
-- 强制刷新:先试 FAST,不行自动降级为 COMPLETE
REFRESH MATERIALIZED VIEW TEST.MV_ORDER_DAY_SUMMARY FORCE;
4、修改刷新计划、删除
-- 修改刷新时间(改为每小时刷新)
ALTER MATERIALIZED VIEW TEST.MV_ORDER_DAY_SUMMARY
REFRESH COMPLETE ON DEMAND
START WITH SYSDATE
NEXT SYSDATE + INTERVAL '1' HOUR;
-- 不再需要时删除
DROP MATERIALIZED VIEW TEST.MV_ORDER_DAY_SUMMARY;
判断标准就一条:结果集是 “算一遍、读很多遍”,就值得物化;如果是 “每次查的数据都不一样”,用了反而浪费空间。
物化视图可以像普通表一样建索引,这是它比普通视图强的地方:
-- 在物化视图上建索引(大幅提升查询速度)
CREATE INDEX IDX_MV_DAILY_SALES_SALE_DATE ON DEMO.MV_DAILY_SALES(SALE_DATE);
CREATE BITMAP INDEX IDX_MV_DAILY_SALES _ORDER_COUNT ON DEMO. MV_DAILY_SALES (ORDER_COUNT);
1. 快速刷新不是所有SQL都支持
官方文档按 SQL 结构把物化视图分成 AGGREGATE(仅分组聚合)、JOIN(仅多表连接)、SUBQUERY(仅子查询)、COMPLEX(其他复杂类型)四类。带 DISTINCT、UNION、外连接等复杂操作的,快速刷新会失败,只能退回 FORCE 或 COMPLETE。设计 SQL 时就要想好刷新策略。
2. 物化视图日志大小要注意,要定期清理
日志会不断累积基表的变更记录,越来越大,影响基表 DML 性能。定期执行:
PURGE MATERIALIZED VIEW LOG ON TEST.ORDER_DETAIL;
3. COMPLETE 刷新会锁基表
完全刷新期间基表会被锁定,业务 DML 会被阻塞。生产环境放业务低峰期执行,或者改用快速刷新。
4. 用数据字典监控刷新状态
刷新失败不会主动报警,数据陈旧了很难发现。查 SYS.USER_MVIEWS 可以看每个物化视图的状态:
SELECT MVIEW_NAME, MVIEW_TYPE, LAST_REFRESH_DATE, STALENESS
FROM USER_MVIEWS;
LAST_REFRESH_DATE 停在好几天前,说明刷新任务已经挂了,要赶紧查刷新任务的报错。
物化视图是 DM8 里 “以空间换时间” 的典型工具:把高频聚合计算前置,换取查询性能的提升。它不复杂,但刷新策略的选择、日志的维护、状态的监控这三件事没做好,优化工具也可能变成新的麻烦。
文章
阅读量
获赞
