使用异步物化视图透明改写

更新时间:
复制 MD 格式

异步物化视图支持多表Join和复杂聚合的预计算,通过定时或增量刷新保持数据新鲜度。查询时优化器可自动将匹配的查询透明改写到物化视图上执行,大幅提升复杂分析查询的性能。本文介绍异步物化视图的创建、刷新策略、透明改写机制及与同步物化视图的差异。

什么是异步物化视图

异步物化视图是一种独立的物理表,通过预先执行查询并存储结果来加速后续相同或相似模式的查询。与同步物化视图相比:

对比维度

同步物化视图(Rollup)

异步物化视图

数据范围

单表聚合/列重排

支持多表Join和复杂计算

数据一致性

实时强一致

最终一致(取决于刷新频率)

刷新方式

导入时同步更新

手动/定时/增量

适用场景

高频单表聚合

复杂报表、多表关联分析

关于异步物化视图的完整语法和详细参数说明,请参见创建、查询和维护异步物化视图

创建异步物化视图

使用CREATE MATERIALIZED VIEW语句创建异步物化视图:

-- 创建多表Join的物化视图,预计算各地区每日销售汇总
CREATE MATERIALIZED VIEW mv_region_daily_sales
BUILD IMMEDIATE
REFRESH AUTO ON SCHEDULE EVERY 1 HOUR
DISTRIBUTED BY HASH(region) BUCKETS 8
AS
SELECT
    o.order_date,
    o.region,
    p.category,
    SUM(o.amount) AS total_amount,
    COUNT(*) AS order_count
FROM orders o
JOIN products p ON o.product_id = p.product_id
GROUP BY o.order_date, o.region, p.category;

关键参数说明:

  • BUILD IMMEDIATE:创建后立即构建数据。也可使用BUILD DEFERRED延迟到首次刷新。

  • REFRESH AUTO ON SCHEDULE EVERY 1 HOUR:每小时自动刷新一次。

  • DISTRIBUTED BY HASH:物化视图的数据分布方式,建议与常用查询的Group By列一致。

刷新策略

异步物化视图支持多种刷新策略:

手动刷新

-- 全量刷新
REFRESH MATERIALIZED VIEW mv_region_daily_sales COMPLETE;

-- 增量刷新(仅刷新变更分区)
REFRESH MATERIALIZED VIEW mv_region_daily_sales AUTO;

定时刷新

-- 修改刷新周期为每30分钟
ALTER MATERIALIZED VIEW mv_region_daily_sales
REFRESH AUTO ON SCHEDULE EVERY 30 MINUTE;

分区增量刷新

当基表为分区表时,SelectDB支持分区级增量刷新,只刷新有数据变更的分区,大幅减少刷新开销:

-- 创建支持分区增量刷新的物化视图
CREATE MATERIALIZED VIEW mv_daily_stats
BUILD IMMEDIATE
REFRESH AUTO ON SCHEDULE EVERY 1 HOUR
PARTITION BY (order_date)
DISTRIBUTED BY HASH(region) BUCKETS 8
AS
SELECT order_date, region, SUM(amount) AS total_amount
FROM orders
GROUP BY order_date, region;

透明改写机制

当开启透明改写功能后,优化器在规划查询时会自动检测是否存在可匹配的物化视图:

-- 开启异步物化视图透明改写(默认开启)
SET enable_materialized_view_rewrite = true;

透明改写的匹配条件:

  • 查询的表、Join条件与物化视图定义一致或为其子集。

  • 查询的聚合函数可以从物化视图的预聚合结果进一步计算得到。

  • 查询的过滤条件可以在物化视图的结果上进一步过滤。

  • 物化视图的数据新鲜度满足grace_period属性设定的容忍时间(单位:秒)。

例如以下查询将被自动改写到mv_region_daily_sales

-- 原始查询:会被透明改写到物化视图
SELECT region, SUM(amount) AS total_amount
FROM orders o
JOIN products p ON o.product_id = p.product_id
WHERE o.order_date >= '2024-01-01'
GROUP BY region;

-- 优化器自动改写为
-- SELECT region, SUM(total_amount) FROM mv_region_daily_sales
-- WHERE order_date >= '2024-01-01' GROUP BY region;

验证透明改写

使用EXPLAIN查看查询是否命中物化视图:

EXPLAIN SELECT region, SUM(amount)
FROM orders o JOIN products p ON o.product_id = p.product_id
GROUP BY region;

-- 输出中如果出现 mv_region_daily_sales 表名,
-- 说明查询已被透明改写到物化视图

查看物化视图状态和刷新情况:

-- 查看物化视图列表及状态
SHOW CREATE MATERIALIZED VIEW mv_region_daily_sales;

-- 查看刷新任务状态
SELECT * FROM tasks('type'='mv') WHERE MvName = 'mv_region_daily_sales'
ORDER BY CreateTime DESC LIMIT 5;

控制改写行为

通过Session变量精细控制透明改写行为:

-- 关闭透明改写(调试时使用)
SET enable_materialized_view_rewrite = false;

-- 设置物化视图的数据新鲜度容忍时间(秒),超过该时间未刷新则不参与改写
ALTER MATERIALIZED VIEW mv_region_daily_sales SET ('grace_period' = '3600');

管理异步物化视图

-- 设置数据新鲜度容忍时间为24小时(超过该时间未刷新则不参与透明改写)
ALTER MATERIALIZED VIEW mv_region_daily_sales SET ('grace_period' = '86400');

-- 删除物化视图
DROP MATERIALIZED VIEW mv_region_daily_sales;

-- 查看物化视图定义
SHOW CREATE MATERIALIZED VIEW mv_region_daily_sales;