Doris 异步物化视图实践:透明改写与自动刷新加速查询性能
Apache Doris(原名 Palo)是一款开源的实时分析型数据库,广泛应用于大数据场景。物化视图是 Doris 提供的一项重要功能,通过预先计算和存储常用查询结果,显著提升查询性能。异步物化视图相比同步物化视图具有更好的灵活性和资源利用率,特别适合数据量大、更新频繁的场景。
Doris 异步物化视图的主要特点包括:
- 支持定义何时刷新(基于时间或数据变更)
- 透明改写机制自动将查询路由到最合适的视图
- 可与基表协同工作,保证数据一致性
- 支持多表聚合场景,实现复杂查询加速
1. Doris 异步物化视图概述
异步物化视图是 Doris 提供的高级查询优化功能,与同步物化视图相比,它不会在基表数据更新时立即刷新,而是按照预设策略(如定时或触发式)进行刷新,从而降低对基表写入性能的影响。
异步物化视图的核心优势在于:
- 资源利用率高,避免写入时消耗大量计算资源
- 可在业务低峰期进行刷新,减少对在线查询的影响
- 支持复杂多表关联预计算,提升复杂查询性能
- 灵活的刷新策略,满足不同业务场景需求
2. 透明改写机制原理与实践
透明改写是 Doris 物化视图的核心优势之一,它允许系统自动判断查询是否可以使用物化视图来加速,而无需修改查询语句。
透明改写的工作原理:
- 解析查询语句,提取查询条件和聚合函数
- 匹配与现有物化视图的定义
- 如果查询能够从物化视图获取全部或部分数据,则使用视图
- 对于无法完全由视图满足的查询,采用视图+基表的混合策略
实践示例:
-- 创建订单表 CREATE TABLE orders ( order_id BIGINT, user_id BIGINT, amount DECIMAL(10,2), order_date DATE ) ENGINE=OLAP DISTRIBUTED BY HASH(user_id) BUCKETS 10 PROPERTIES ("replication_num" = "1"); -- 创建订单明细表 CREATE TABLE order_items ( item_id BIGINT, order_id BIGINT, product_id BIGINT, quantity INT, price DECIMAL(10,2) ) ENGINE=OLAP DISTRIBUTED BY HASH(order_id) BUCKETS 10 PROPERTIES ("replication_num" = "1"); -- 创建异步物化视图,统计用户每日订单总额 CREATE MATERIALIZED VIEW user_daily_order_mv BUILD DEFERRED REFRESH AUTO ON SCHEDULE EVERY 1 DAY PROPERTIES ( "auto_refresh" = "true" ) AS SELECT user_id, order_date, SUM(amount) AS total_amount FROM orders GROUP BY user_id, order_date;上述物化视图会每天自动刷新一次,当执行如下查询时,Doris 会自动使用该视图加速:
-- 查询用户每日订单总额 SELECT user_id, order_date, SUM(amount) FROM orders GROUP BY user_id, order_date;3. 自动刷新功能配置与优化
Doris 异步物化视图提供了灵活的自动刷新机制,可以基于时间或数据变更触发刷新。
基于时间的自动刷新:
CREATE MATERIALIZED VIEW daily_sales_mv BUILD DEFERRED REFRESH AUTO ON SCHEDULE EVERY 1 DAY PROPERTIES ( "auto_refresh" = "true", "refresh_start_time" = "02:00:00" ) AS SELECT order_date, COUNT(*) AS order_count, SUM(amount) AS total_amount FROM orders GROUP BY order_date;基于数据变更的自动刷新:
CREATE MATERIALIZED VIEW user_order_summary_mv BUILD DEFERRED REFRESH AUTO ON COMMIT PROPERTIES ( "auto_refresh" = "true" ) AS SELECT user_id, COUNT(*) AS order_count, SUM(amount) AS total_amount FROM orders GROUP BY user_id;自动刷新优化策略:
- 合理设置刷新频率,避免过于频繁消耗资源
- 对于大表物化视图,考虑使用增量刷新策略
- 在业务低峰期执行刷新操作,减少对在线查询的影响
- 监控刷新性能,及时调整参数
4. 多表聚合加速场景应用
在数据分析场景中,经常需要关联多表并执行聚合操作,这是异步物化视图的重要应用场景。
多表物化视图示例:
-- 创建产品表 CREATE TABLE products ( product_id BIGINT, category_id BIGINT, product_name VARCHAR(100), price DECIMAL(10,2) ) ENGINE=OLAP DISTRIBUTED BY HASH(product_id) BUCKETS 10 PROPERTIES ("replication_num" = "1"); -- 创建多表物化视图,统计各类产品销售额 CREATE MATERIALIZED VIEW category_sales_mv BUILD DEFERRED REFRESH AUTO ON SCHEDULE EVERY 2 HOUR PROPERTIES ( "auto_refresh" = "true" ) AS SELECT p.category_id, COUNT(DISTINCT o.order_id) AS order_count, SUM(oi.quantity * oi.price) AS total_sales FROM orders o JOIN order_items oi ON o.order_id = oi.order_id JOIN products p ON oi.product_id = p.product_id GROUP BY p.category_id;该物化视图通过关联三张表,预先计算各类产品的销售数据,当执行如下查询时,Doris 会直接使用物化视图结果:
-- 查询各类产品销售情况 SELECT p.category_id, COUNT(DISTINCT o.order_id) AS order_count, SUM(oi.quantity * oi.price) AS total_sales FROM orders o JOIN order_items oi ON o.order_id = oi.order_id JOIN products p ON oi.product_id = p.product_id GROUP BY p.category_id;5. 实战案例与注意事项
完整示例:
-- 1. 创建基表 CREATE TABLE sales ( id BIGINT, date DATE, store_id INT, product_id INT, quantity INT, amount DECIMAL(10,2) ) ENGINE=OLAP DISTRIBUTED BY HASH(store_id) BUCKETS 10 PROPERTIES ("replication_num" = "1"); -- 2. 创建异步物化视图,按门店统计日销售额 CREATE MATERIALIZED VIEW store_daily_sales_mv BUILD DEFERRED REFRESH AUTO ON SCHEDULE EVERY 1 DAY PROPERTIES ( "auto_refresh" = "true" ) AS SELECT store_id, date, SUM(amount) AS total_sales, SUM(quantity) AS total_quantity FROM sales GROUP BY store_id, date; -- 3. 创建异步物化视图,统计产品月销量 CREATE MATERIALIZED VIEW product_monthly_sales_mv BUILD DEFERRED REFRESH AUTO ON SCHEDULE EVERY 1 DAY PROPERTIES ( "auto_refresh" = "true" ) AS SELECT product_id, DATE_FORMAT(date, '%Y-%m') AS month, SUM(amount) AS total_sales, SUM(quantity) AS total_quantity FROM sales GROUP BY product_id, DATE_FORMAT(date, '%Y-%m'); -- 4. 查询1:使用门店日销售额物化视图 SELECT store_id, date, total_sales FROM store_daily_sales_mv WHERE date = '2023-01-01'; -- 5. 查询2:使用产品月销量物化视图 SELECT product_id, month, total_quantity FROM product_monthly_sales_mv WHERE month = '2023-01';注意事项:
- 物化视图的查询条件必须完全匹配才能被改写,建议经常使用的查询场景创建专门的物化视图
- 大表物化视图会占用大量存储空间,需要合理规划
- 频繁更新基表数据时,自动刷新可能会影响性能,可考虑在业务低峰期设置刷新
- 物化视图不支持所有查询场景,复杂查询可能仍需直接查询基表
- 定期检查物化视图是否被有效使用,及时清理无用视图以节省资源
异步物化视图工作流程
不同物化视图策略对比
| 策略类型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 同步物化视图 | 数据实时性高,无需额外刷新机制 | 每次基表更新都触发刷新,影响性能 | 数据更新不频繁,查询实时性要求高 |
| 异步物化视图 | 减少对基表更新的性能影响,灵活设置刷新时间 | 数据存在一定延迟 | 数据量大,更新频繁,允许一定延迟 |
| 增量刷新策略 | 节省刷新资源,仅处理变更数据 | 实现复杂,需额外管理增量数据 | 超大表物化视图,资源有限 |
| 触发式刷新 | 精准控制刷新时机,资源利用率高 | 需要明确触发条件,增加系统复杂性 | 业务有明显周期性,需特定条件刷新 |