This is an automated email from the ASF dual-hosted git repository. kassiez pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris-website.git
The following commit(s) were added to refs/heads/master by this push: new f2402bc79af [doc](mtmv) Async materialized view doc optimize (#1473) f2402bc79af is described below commit f2402bc79af090e76360d15cbef52bcb9e4d123b Author: seawinde <w...@selectdb.com> AuthorDate: Fri Dec 27 19:32:30 2024 +0800 [doc](mtmv) Async materialized view doc optimize (#1473) ## Versions Need preview - [x] dev - [ ] 3.0 - [ ] 2.1 - [ ] 2.0 ## Languages - [x] Chinese - [ ] English ## Docs Checklist - [ ] Checked by AI - [ ] Test Cases Built --- .../async-materialized-view/faq.md | 32 +- .../functions-and-demands.md | 745 ++++++++++++++++----- .../async-materialized-view/overview.md | 548 ++------------- .../async-materialized-view/use-guide.md | 478 ++++++++----- .../Create/CREATE-ASYNC-MATERIALIZED-VIEW.md | 5 + 5 files changed, 938 insertions(+), 870 deletions(-) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/faq.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/faq.md index 72068e39c7c..53e066e5149 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/faq.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/faq.md @@ -92,7 +92,7 @@ Unable to find a suitable base table for partitioning - 最新的代码可以提示分区构建失败的原因,原因摘要和说明见附录 2 -**举例如下:** +**例如:** ```sql CREATE TABLE IF NOT EXISTS orders ( @@ -108,7 +108,7 @@ CREATE TABLE IF NOT EXISTS orders ( ) DUPLICATE KEY(o_orderkey, o_custkey) PARTITION BY RANGE(o_orderdate) ( FROM ('2024-05-01') TO ('2024-06-30') INTERVAL 1 DAY -) DISTRIBUTED BY HASH(o_orderkey) BUCKETS 3 PROPERTIES ("replication_num" = "1"); +) DISTRIBUTED BY HASH(o_orderkey) BUCKETS 3; CREATE TABLE IF NOT EXISTS lineitem ( @@ -131,7 +131,7 @@ CREATE TABLE IF NOT EXISTS lineitem ( ) DUPLICATE KEY( l_orderkey, l_partkey, l_suppkey, l_linenumber -) DISTRIBUTED BY HASH(l_orderkey) BUCKETS 3 PROPERTIES ("replication_num" = "1"); +) DISTRIBUTED BY HASH(l_orderkey) BUCKETS 3; ``` 物化视图定义如下,可以进行分区增量更新。如果选择`orders.o_orderdate`作为物化视图的分区字段,那么它是可以支持增量分区更新的。相反,如果使用了`lineitem.l_shipdate`,则不能实现增量更新。 @@ -143,7 +143,12 @@ CREATE TABLE IF NOT EXISTS lineitem ( 2. `lineitem.l_shipdate`是`outer join`操作中产生`null`值那一端的列。 ```sql -CREATE MATERIALIZED VIEW mv_1 BUILD IMMEDIATE REFRESH AUTO ON MANUAL partition by(o_orderdate) DISTRIBUTED BY RANDOM BUCKETS 2 PROPERTIES ('replication_num' = '1') AS +CREATE MATERIALIZED VIEW mv_1 + BUILD IMMEDIATE + REFRESH AUTO ON MANUAL + partition by(o_orderdate) + DISTRIBUTED BY RANDOM BUCKETS 2 + AS SELECT l_linestatus, sum( @@ -193,7 +198,6 @@ CREATE MATERIALIZED VIEW mv11 BUILD IMMEDIATE REFRESH AUTO ON MANUAL partition by(l_shipdate) DISTRIBUTED BY HASH(l_orderkey) BUCKETS 10 -PROPERTIES ('replication_num' = '1') AS SELECT l_shipdate, l_orderkey, O_ORDERDATE, count(*) FROM lineitem @@ -221,7 +225,7 @@ GROUP BY l_shipdate, l_orderkey, O_ORDERDATE; - 如果 explain 最后没有出现 `MaterializedView` 等信息,那么意味着此物化视图状态不可用,因此不能参与透明改写。(关于什么情况下会导致物化视图状态不可用,可详细参考使用与实践 - 查看物化视图状态)。 -举例如下: +例如: ```sql | MaterializedView | @@ -362,19 +366,7 @@ Explain 显示的信息如下: ## 附录 -### 1 物化视图相关开关介绍 - -| 开关 | 说明 | -| ------------------------------------------------------------ | ------------------------------------------------------------ | -| SET enable_nereids_planner = true; | 异步物化视图只有在新优化器下才支持,所以物化视图透明改写没有生效时,需要开启新优化器 | -| SET enable_materialized_view_rewrite = true; | 开启或者关闭查询透明改写,默认开启 | -| SET materialized_view_rewrite_enable_contain_external_table = true; | 参与透明改写的物化视图是否允许包含外表,默认不允许,如果物化视图的定义 SQL 中包含外表,也想参与到透明改写,可以打开此开关。 | -| SET materialized_view_rewrite_success_candidate_num = 3; | 透明改写成功的结果集合,允许参与到 CBO 候选的最大数量,默认是 3。如果发现透明改写的性能很慢,可以考虑把这个值调小。 | -| SET enable_materialized_view_union_rewrite = true; | 当分区物化视图不足以提供查询的全部数据时,是否允许基表和物化视图 union all 来响应查询,默认允许。如果发现命中物化视图时数据错误,可以把这个开关关闭。 | -| SET enable_materialized_view_nest_rewrite = true; | 是否允许嵌套改写,默认不允许。如果查询 SQL 很复杂,需要构建嵌套物化视图才可以命中,那么需要打开此开关。 | -| SET materialized_view_relation_mapping_max_count = 8; | 透明改写过程中,relation mapping 最大允许数量,如果超过,进行截取。relation mapping 通常由表自关联产生,数量一般会是笛卡尔积,比如 3 张表,可能会产生 8 种组合。默认是 8。如果发现透明改写时间很长,可以把这个值调低 | - -### 2 透明改写失败摘要信息和说明 +### 1 透明改写失败摘要信息和说明 | 摘要信息 | 说明 | | ------------------------------------------------------------ | ------------------------------------------------------------ | @@ -405,7 +397,7 @@ Explain 显示的信息如下: | Both query and view have group sets, or query doesn't have but view has, not supported | 查询和物化视图都有 group sets 查询没有 group sets,但是物化视图有,这种不支持透明改写 | | | | -### 3 异步物化视图分区构建物化视图失败原因和说明 +### 2 异步物化视图分区构建物化视图失败原因和说明 分区物化视图的刷新原理是分区增量更新: diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/functions-and-demands.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/functions-and-demands.md index b470ff4a83d..3b854eac249 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/functions-and-demands.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/functions-and-demands.md @@ -1,6 +1,6 @@ --- { - "title": "异步物化视图功能描述", + "title": "创建、查询与维护异步物化视图", "language": "zh-CN" } --- @@ -24,229 +24,367 @@ specific language governing permissions and limitations under the License. --> -本文将详细说明物化视图 DDL 和基础运维、元数据查询、权限说明、物化刷新数据湖支持情况、与 OLAP 内表关系、直查、查询改写等功能以及基础命令。 +本文将详细说明物化视图 DDL,物化视图直查、查询改写和物化视图常见运维。 +## 物化视图 DDL +### 权限说明 -## DDL 和基础运维 +- 创建物化视图:需要具有有物化视图的创建权限(与建表权限相同)以及创建物化视图查询语句的查询权限(与 SELECT 权限相同)。 + +- 删除物化视图:需要具有物化视图的删除权限(与删除表权限相同)。 + +- 修改物化视图:需要具有物化视图的修改权限(与修改表权限相同)。 ### 物化视图创建 +建表语句如下: -**1. 详情参考** **[CREATE ASYNC MATERIALIZED VIEW](../../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-ASYNC-MATERIALIZED-VIEW)** +```sql +CREATE TABLE IF NOT EXISTS lineitem ( + l_orderkey integer not null, + l_partkey integer not null, + l_suppkey integer not null, + l_linenumber integer not null, + l_quantity decimalv3(15,2) not null, + l_extendedprice decimalv3(15,2) not null, + l_discount decimalv3(15,2) not null, + l_tax decimalv3(15,2) not null, + l_returnflag char(1) not null, + l_linestatus char(1) not null, + l_shipdate date not null, + l_commitdate date not null, + l_receiptdate date not null, + l_shipinstruct char(25) not null, + l_shipmode char(10) not null, + l_comment varchar(44) not null + ) + DUPLICATE KEY(l_orderkey, l_partkey, l_suppkey, l_linenumber) + PARTITION BY RANGE(l_shipdate) + (FROM ('2023-10-17') TO ('2023-11-01') INTERVAL 1 DAY) + DISTRIBUTED BY HASH(l_orderkey) BUCKETS 3; -**2. 新增属性** +INSERT INTO lineitem VALUES +(1, 2, 3, 4, 5.5, 6.5, 7.5, 8.5, 'o', 'k', '2023-10-17', '2023-10-17', '2023-10-17', 'a', 'b', 'yyyyyyyyy'), +(2, 4, 3, 4, 5.5, 6.5, 7.5, 8.5, 'o', 'k', '2023-10-18', '2023-10-18', '2023-10-18', 'a', 'b', 'yyyyyyyyy'), +(3, 2, 4, 4, 5.5, 6.5, 7.5, 8.5, 'o', 'k', '2023-10-19', '2023-10-19', '2023-10-19', 'a', 'b', 'yyyyyyyyy'); -- use_for_rewrite::标识此物化视图是否参与到透明改写中,如果为 false,不参与到透明改写,默认是 true。数据建模场景中,如果物化视图只是用于直查,物化视图可以设置此属性,从而不参与透明改写,提高查询响应速度。 +CREATE TABLE IF NOT EXISTS orders ( + o_orderkey integer not null, + o_custkey integer not null, + o_orderstatus char(1) not null, + o_totalprice decimalv3(15,2) not null, + o_orderdate date not null, + o_orderpriority char(15) not null, + o_clerk char(15) not null, + o_shippriority integer not null, + o_comment varchar(79) not null + ) +DUPLICATE KEY(o_orderkey, o_custkey) +PARTITION BY RANGE(o_orderdate)( +FROM ('2023-10-17') TO ('2023-11-01') INTERVAL 1 DAY) +DISTRIBUTED BY HASH(o_orderkey) BUCKETS 3; + +INSERT INTO orders VALUES +(1, 1, 'o', 9.5, '2023-10-17', 'a', 'b', 1, 'yy'), +(1, 1, 'o', 10.5, '2023-10-18', 'a', 'b', 1, 'yy'), +(2, 1, 'o', 11.5, '2023-10-19', 'a', 'b', 1, 'yy'), +(3, 1, 'o', 12.5, '2023-10-19', 'a', 'b', 1, 'yy'); + +CREATE TABLE IF NOT EXISTS partsupp ( + ps_partkey INTEGER NOT NULL, + ps_suppkey INTEGER NOT NULL, + ps_availqty INTEGER NOT NULL, + ps_supplycost DECIMALV3(15,2) NOT NULL, + ps_comment VARCHAR(199) NOT NULL + ) +DUPLICATE KEY(ps_partkey, ps_suppkey) +DISTRIBUTED BY HASH(ps_partkey) BUCKETS 3; -**3. 分区物化视图** +INSERT INTO partsupp VALUES +(2, 3, 9, 10.01, 'supply1'), +(4, 3, 10, 11.01, 'supply2'), +(2, 3, 10, 11.01, 'supply3'); +``` -创建分区物化视图时,对于分区字段引用的表达式,仅允许使用 `date_trunc` 函数和常量。以下语句是符合要求的: +#### 全量物化视图 -分区字段引用的列仅使用了 `date_trunc` 函数。 +触发方式是手动,刷新方式是 AUTO,如下 ```sql -CREATE MATERIALIZED VIEW mv_1 BUILD IMMEDIATE REFRESH AUTO ON MANUAL -partition by (date_alias) +CREATE MATERIALIZED VIEW mv_1_0 +BUILD IMMEDIATE REFRESH AUTO ON MANUAL DISTRIBUTED BY RANDOM BUCKETS 2 -PROPERTIES ('replication_num' = '1') AS SELECT l_linestatus, - date_trunc(o_orderdate) as date_alias, + to_date(o_orderdate) as date_alias, o_shippriority FROM orders LEFT JOIN lineitem ON l_orderkey = o_orderkey; ``` -以下示例则无法创建分区物化视图,因为分区字段引用的表达式使用了 `to_date` 函数: +延迟刷新,首次刷新时间是 `2024-12-01 20:30:00`, 并且每隔一天刷新一次。如果 `BUILD DEFERRED` 指定为 `BUILD IMMEDIATE` 创建 +完物化视图会立即刷新一次。之后从 `2024-12-01 20:30:00` 每隔一天刷新一次 +注意 STARTS 的时间要晚于当前的时间。如下 ```sql -CREATE MATERIALIZED VIEW mv_1 BUILD IMMEDIATE REFRESH AUTO ON MANUAL -partition by (date_alias) -DISTRIBUTED BY RANDOM BUCKETS 2 +CREATE MATERIALIZED VIEW mv_1_1 +BUILD DEFERRED +REFRESH COMPLETE +ON SCHEDULE EVERY 1 DAY STARTS '2024-12-01 20:30:00' PROPERTIES ('replication_num' = '1') AS SELECT - l_linestatus, - to_date(o_orderdate) as date_alias, - o_shippriority +l_linestatus, +to_date(o_orderdate) as date_alias, +o_shippriority FROM - orders - LEFT JOIN lineitem ON l_orderkey = o_orderkey; +orders +LEFT JOIN lineitem ON l_orderkey = o_orderkey; ``` -### 物化视图修改 +刷新方式是触发式,当 orders 或者 lineitem 表数据发生变化的时候,会自动触发物化视图的刷新。如下 -详情参考 [ALTER ASYNC MATERIALIZED VIEW](../../../sql-manual/sql-statements/Data-Definition-Statements/Alter/ALTER-ASYNC-MATERIALIZED-VIEW) - -### 物化视图删除 +```sql +CREATE MATERIALIZED VIEW mv_1_1 +BUILD IMMEDIATE +REFRESH COMPLETE +ON COMMIT +PROPERTIES ('replication_num' = '1') +AS +SELECT +l_linestatus, +to_date(o_orderdate) as date_alias, +o_shippriority +FROM +orders +LEFT JOIN lineitem ON l_orderkey = o_orderkey; +``` -详情参考 [DROP ASYNC MATERIALIZED VIEW](../../../sql-manual/sql-statements/Data-Definition-Statements/Drop/DROP-ASYNC-MATERIALIZED-VIEW) +注意:**如果基表的数据频繁变更,不太适合使用此种方式刷新,因为会频繁构建物化刷新任务,消耗过多资源**。 -### 刷新物化视图 +#### 分区物化视图 -详情参考 [REFRESH MATERIALIZED VIEW](../../../sql-manual/sql-statements/Utility-Statements/REFRESH-MATERIALIZED-VIEW/) +创建分区物化视图时,需要指定 `partition by`,对于分区字段引用的表达式,仅允许使用 `date_trunc` 函数和标识符。以下语句是符合要求的: +分区字段引用的列仅使用了 `date_trunc` 函数。 -### 暂停物化视图 +```sql +CREATE MATERIALIZED VIEW mv_2_0 BUILD IMMEDIATE REFRESH AUTO ON MANUAL +partition by (order_date_month) +DISTRIBUTED BY RANDOM BUCKETS 2 +AS +SELECT + l_linestatus, + date_trunc(o_orderdate, 'month') as order_date_month, + o_shippriority +FROM + orders + LEFT JOIN lineitem ON l_orderkey = o_orderkey; +``` -详情参考 [PAUSE MATERIALIZED VIEW](../../../sql-manual/sql-statements/Utility-Statements/PAUSE-MATERIALIZED-VIEW) +如下语句创建分区物化视图会失败,因为分区字段 `order_date_month` 使用了 `date_add()` 函数 +报错 `because column to check use invalid implicit expression, invalid expression is days_add(o_orderdate#4, 2)` -### 启用物化视图 +```sql +CREATE MATERIALIZED VIEW mv_2_1 BUILD IMMEDIATE REFRESH AUTO ON MANUAL +partition by (order_date_month) +DISTRIBUTED BY RANDOM BUCKETS 2 +AS +SELECT + l_linestatus, + date_trunc(date_add(o_orderdate, INTERVAL 2 DAY), 'month') as order_date_month, + o_shippriority +FROM + orders + LEFT JOIN lineitem ON l_orderkey = o_orderkey; +``` -详情参考 [RESUME MATERIALIZED VIEW](../../../sql-manual/sql-statements/Utility-Statements/RESUME-MATERIALIZED-VIEW) +**基表有多列分区** -### 取消物化视图刷新任务 +:::tip 提示 +自 Doris 2.1.0 版本起支持多列分区 +::: -详情参考 [CANCEL MATERIALIZED VIEW TASK](../../../sql-manual/sql-statements/Utility-Statements/CANCEL-MATERIALIZED-VIEW-TASK) +目前仅支持 Hive 外表有多列分区。Hive 外表有很多多级分区的情况,例如一级分区按照日期,二级分区按照区域。物化视图可以选择 Hive 的某一级分区列作为物化视图的分区列。 +例如,Hive 的建表语句如下: +```sql +CREATE TABLE hive1 ( +`k1` int) +PARTITIONED BY ( +`year` int, +`region` string) +STORED AS ORC; + +alter table hive1 add if not exists +partition(year=2020,region="bj") +partition(year=2020,region="sh") +partition(year=2021,region="bj") +partition(year=2021,region="sh") +partition(year=2022,region="bj") +partition(year=2022,region="sh") +``` -## 元数据查询 +当物化视图的创建语句如下时,物化视图`mv_hive`将有三个分区:`('2020'),('2021'),('2022')` -- 查询物化视图信息:[MV_INFOS](../../../sql-manual/sql-functions/table-valued-functions/mv-infos) +```sql +CREATE MATERIALIZED VIEW mv_hive +BUILD DEFERRED REFRESH AUTO ON MANUAL +partition by(`year`) +DISTRIBUTED BY RANDOM BUCKETS 2 +AS +SELECT k1,year,region FROM hive1; +``` -- 查询 TASK 信息:[TASKS](../../../sql-manual/sql-functions/table-valued-functions/tasks?_highlight=task) +当物化视图的建表语句如下时,那么物化视图`mv_hive2`将有如下两个分区:`('bj')`,`('sh')`: -- 查询物化视图对应的 JOB 信息:[JOBS](../../../sql-manual/sql-functions/table-valued-functions/jobs) +```sql +CREATE MATERIALIZED VIEW mv_hive2 +BUILD DEFERRED REFRESH AUTO ON MANUAL +partition by(`region`) +DISTRIBUTED BY RANDOM BUCKETS 2 +AS +SELECT k1,year,region FROM hive1; +``` -- 查询物化视图的分区信息:[SHOW PARTITIONS](../../../sql-manual/sql-statements/Show-Statements/SHOW-PARTITIONS) +**使用基表部分分区** -- 查看物化视图表结构:[DESCRIBE](../../../sql-manual/sql-statements/Utility-Statements/DESCRIBE) +:::tip 提示 +自 Doris 2.1.1 版本起支持此功能 +::: -- 查看物化视图创建语句:[SHOW CREATE MATERIALIZED VIEW](../../../sql-manual/sql-statements/Show-Statements/SHOW-CREATE-MATERIALIZED-VIEW/) +有些基表有很多分区,但是物化视图只关注最近一段时间的“热”数据,那么可以使用此功能。 -## 权限说明 +基表的建表语句如下: -- 创建物化视图:需要具有有物化视图的创建权限(与建表权限相同)以及创建物化视图查询语句的查询权限(与 SELECT 权限相同)。 +```sql +CREATE TABLE t1 ( + `k1` INT, + `k2` DATE NOT NULL +) ENGINE=OLAP +DUPLICATE KEY(`k1`) +COMMENT 'OLAP' +PARTITION BY range(`k2`) +( +PARTITION p26 VALUES [("2024-03-26"),("2024-03-27")), +PARTITION p27 VALUES [("2024-03-27"),("2024-03-28")), +PARTITION p28 VALUES [("2024-03-28"),("2024-03-29")) +) +DISTRIBUTED BY HASH(`k1`) BUCKETS 2; +``` -- 删除物化视图:需要具有物化视图的删除权限(与删除表权限相同)。 +物化视图的创建语句如以下举例,代表物化视图只关注最近一天的数据。若当前时间为 2024-03-28 xx:xx:xx,这样物化视图会仅有一个分区 `[("2024-03-28"),("2024-03-29")]`: -- 修改物化视图:需要具有物化视图的修改权限(与修改表权限相同)。 +```sql +CREATE MATERIALIZED VIEW mv1 +BUILD DEFERRED REFRESH AUTO ON MANUAL +partition by(`k2`) +DISTRIBUTED BY RANDOM BUCKETS 2 +PROPERTIES ( +'partition_sync_limit'='1', +'partition_sync_time_unit'='DAY' +) +AS +SELECT * FROM t1; +``` -- 暂停/恢复/取消/刷新物化视图:需要具有物化视图的创建权限。 +若时间又过了一天,当前时间为` 2024-03-29 xx:xx:xx`,`t1`则会新增一个分区 `[("2024-03-29"),("2024-03-30")]`,若此时刷新物化视图,刷新完成后,物化视图会仅有一个分区 `[("2024-03-29"),("2024-03-30")]`。 -## 物化刷新数据湖支持情况 +此外,分区字段是字符串类型时,可以设置物化视图属性 `partition_date_format`,例如 `%Y-%m-%d` 。 -对于物化刷新数据湖的支持情况,不同类型的表和 Catalog 有不同的支持程度: +**分区上卷** -| 表类型 | Catalog 类型 | 全量刷新 | 分区刷新 | 触发刷新 | -| ------- | ------------ | -------- | -------- | --------- | -| 内表 | Internal | 2.1 支持 | 2.1 支持 | 2.1.4 支持 | -| 外表 | Hive | 2.1 支持 | 2.1 支持 | 不支持 | -| Iceberg | 支持 | 不支持 | 不支持 | | -| Paimon | 支持 | 不支持 | 不支持 | | -| Hudi | 支持 | 不支持 | 不支持 | | -| JDBC | 支持 | 不支持 | 不支持 | | -| ES | 支持 | 不支持 | 不支持 | | +:::tip 提示 +自 Doris 2.1.5 版本起支持此功能 +::: -## 物化视图和 OLAP 内表关系 +当基表数据经过聚合处理后,各分区的数据量可能会显著减少。在这种情况下,可以采用分区上卷策略,以降低物化视图的分区数量。 -:::tips -自 2.1.4 版本起,物化视图支持 Duplicate 模型 -::: +- Range 分区 -物化视图的底层实现是一个 Duplicate 模型的 OLAP 表。这意味着,理论上物化视图支持 Duplicate 模型的所有功能。然而,为了确保物化视图能够正常且高效地刷新数据,对其功能进行了一些限制: + 假设基表的建表语句如下: -1. 物化视图的分区是基于其基表自动创建和维护的,因此用户不能对物化视图进行分区操作。 + ```sql + CREATE TABLE `t1` ( + `k1` LARGEINT NOT NULL, + `k2` DATE NOT NULL + ) ENGINE=OLAP + DUPLICATE KEY(`k1`) + COMMENT 'OLAP' + PARTITION BY range(`k2`) + ( + PARTITION p_20200101 VALUES [("2020-01-01"),("2020-01-02")), + PARTITION p_20200102 VALUES [("2020-01-02"),("2020-01-03")), + PARTITION p_20200201 VALUES [("2020-02-01"),("2020-02-02")) + ) + DISTRIBUTED BY HASH(`k1`) BUCKETS 2; + ``` -2. 由于物化视图背后有相关的作业(JOB)需要处理,所以不能使用删除表(DELETE TABLE)或重命名表(RENAME TABLE)的命令来操作物化视图。相反,需要使用物化视图自身的命令来进行这些操作。 + 若物化视图的创建语句如下,则该物化视图将包含两个分区:`[("2020-01-01","2020-02-01")] `和` [("2020-02-01","2020-03-01")]` -3. 物化视图的列数据类型是根据查询语句推导出来的,因此这些数据类型不能被修改。否则,可能会导致物化视图的刷新任务失败。 + ```sql + CREATE MATERIALIZED VIEW mv_3 + BUILD DEFERRED REFRESH AUTO ON MANUAL + partition by (date_trunc(`k2`,'month')) + DISTRIBUTED BY RANDOM BUCKETS 2 + AS + SELECT * FROM t1; + ``` -4. 物化视图具有一些 Duplicate 表没有的属性(property),这些属性需要通过物化视图的命令进行修改。而其他公用的属性则需要使用 ALTER TABLE 命令进行修改。 + 若物化视图的创建语句如下,则该物化视图将只包含一个分区:`[("2020-01-01","2021-01-01")]` -5. DESC、SHOW PARTITIONS 等命令同样适用于物化视图,可以用于查看物化视图的描述信息和分区信息。 + ```sql + CREATE MATERIALIZED VIEW mv_4 + BUILD DEFERRED REFRESH AUTO ON MANUAL + partition by (date_trunc(`k2`,'year')) + DISTRIBUTED BY RANDOM BUCKETS 2 + AS + SELECT * FROM t1; + ``` -6. 物化视图支持创建索引。 +此外,如果分区字段为字符串类型,可以通过设置物化视图的 `partition_date_format` 属性来指定日期格式,例如 `'%Y-%m-%d'`。 -7. 用户可以基于一个物化视图创建同步物化视图。 +**详情参考** **[CREATE ASYNC MATERIALIZED VIEW](../../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-ASYNC-MATERIALIZED-VIEW)** -## 直查 +### 物化视图修改 +```sql +ALTER MATERIALIZED VIEW mv_1 +SET( + "grace_period" = "10" +); +``` +详情参考 [ALTER ASYNC MATERIALIZED VIEW](../../../sql-manual/sql-statements/Data-Definition-Statements/Alter/ALTER-ASYNC-MATERIALIZED-VIEW) -建表语句如下: +### 物化视图删除 ```sql -CREATE TABLE IF NOT EXISTS lineitem ( - l_orderkey integer not null, - l_partkey integer not null, - l_suppkey integer not null, - l_linenumber integer not null, - l_quantity decimalv3(15,2) not null, - l_extendedprice decimalv3(15,2) not null, - l_discount decimalv3(15,2) not null, - l_tax decimalv3(15,2) not null, - l_returnflag char(1) not null, - l_linestatus char(1) not null, - l_shipdate date not null, - l_commitdate date not null, - l_receiptdate date not null, - l_shipinstruct char(25) not null, - l_shipmode char(10) not null, - l_comment varchar(44) not null - ) - DUPLICATE KEY(l_orderkey, l_partkey, l_suppkey, l_linenumber) - PARTITION BY RANGE(l_shipdate) -(FROM ('2023-10-17') TO ('2023-11-01') INTERVAL 1 DAY) - DISTRIBUTED BY HASH(l_orderkey) BUCKETS 3 - PROPERTIES ("replication_num" = "1"); +DROP MATERIALIZED VIEW mv_1; +``` + +详情参考 [DROP ASYNC MATERIALIZED VIEW](../../../sql-manual/sql-statements/Data-Definition-Statements/Drop/DROP-ASYNC-MATERIALIZED-VIEW) -insert into lineitem values -(1, 2, 3, 4, 5.5, 6.5, 7.5, 8.5, 'o', 'k', '2023-10-17', '2023-10-17', '2023-10-17', 'a', 'b', 'yyyyyyyyy'), -(2, 4, 3, 4, 5.5, 6.5, 7.5, 8.5, 'o', 'k', '2023-10-18', '2023-10-18', '2023-10-18', 'a', 'b', 'yyyyyyyyy'), -(3, 2, 4, 4, 5.5, 6.5, 7.5, 8.5, 'o', 'k', '2023-10-19', '2023-10-19', '2023-10-19', 'a', 'b', 'yyyyyyyyy'); -CREATE TABLE IF NOT EXISTS orders ( - o_orderkey integer not null, - o_custkey integer not null, - o_orderstatus char(1) not null, - o_totalprice decimalv3(15,2) not null, - o_orderdate date not null, - o_orderpriority char(15) not null, - o_clerk char(15) not null, - o_shippriority integer not null, - o_comment varchar(79) not null - ) - DUPLICATE KEY(o_orderkey, o_custkey) - PARTITION BY RANGE(o_orderdate)( - FROM ('2023-10-17') TO ('2023-11-01') INTERVAL 1 DAY) - DISTRIBUTED BY HASH(o_orderkey) BUCKETS 3 - PROPERTIES ("replication_num" = "1"); - - insert into orders values - (1, 1, 'o', 9.5, '2023-10-17', 'a', 'b', 1, 'yy'), - (1, 1, 'o', 10.5, '2023-10-18', 'a', 'b', 1, 'yy'), - (2, 1, 'o', 11.5, '2023-10-19', 'a', 'b', 1, 'yy'), - (3, 1, 'o', 12.5, '2023-10-19', 'a', 'b', 1, 'yy'); - CREATE TABLE IF NOT EXISTS partsupp ( - ps_partkey INTEGER NOT NULL, - ps_suppkey INTEGER NOT NULL, - ps_availqty INTEGER NOT NULL, - ps_supplycost DECIMALV3(15,2) NOT NULL, - ps_comment VARCHAR(199) NOT NULL - ) - DUPLICATE KEY(ps_partkey, ps_suppkey) - DISTRIBUTED BY HASH(ps_partkey) BUCKETS 3 - PROPERTIES ( - "replication_num" = "1" - ); - insert into partsupp values - (2, 3, 9, 10.01, 'supply1'), - (4, 3, 10, 11.01, 'supply2'), - (2, 3, 10, 11.01, 'supply3'); +### 查看物化视图创建语句 +```sql +SHOW CREATE MATERIALIZED VIEW mv_1; ``` +详情参考 [SHOW CREATE MATERIALIZED VIEW](../../../sql-manual/sql-statements/Show-Statements/SHOW-CREATE-MATERIALIZED-VIEW/) + +## 查询异步物化视图 + 物化视图可以看作是表,可以像正常的表一样直接查询。 -举例如下: +**物化视图的定义:** -**1. 物化视图的定义:** +### 直查物化视图 ```sql -CREATE MATERIALIZED VIEW mv1 +CREATE MATERIALIZED VIEW mv_5 BUILD IMMEDIATE REFRESH AUTO ON SCHEDULE EVERY 1 hour DISTRIBUTED BY RANDOM BUCKETS 3 -PROPERTIES ('replication_num' = '1') AS SELECT t1.l_linenumber, o_custkey, @@ -256,9 +394,7 @@ LEFT OUTER JOIN orders ON l_orderkey = o_orderkey; ``` -详情可参考 [CREATE-ASYNC-MATERIALIZED-VIEW](../../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-ASYNC-MATERIALIZED-VIEW) - -**2. 查询语句:** +**直接查询语句:** 可以对物化视图添加过滤条件和聚合等,进行直接查询。 @@ -266,12 +402,10 @@ ON l_orderkey = o_orderkey; SELECT l_linenumber, o_custkey -FROM mv1 +FROM mv_5 WHERE l_linenumber > 1 and o_orderdate = '2023-10-18'; ``` -## 查询改写的能力边界 - ### 条件补偿 当物化视图和查询的 `where` 条件是通过 `and` 连接的表达式时: @@ -316,7 +450,7 @@ JOIN 改写指的是查询和物化使用的表相同,可以在物化视图和 - RIGHT ANTI JOIN -举例如下: +例如: 如下查询可进行透明改写,条件 `l_linenumber > 1` 可以上拉,从而进行透明改写,使用物化视图的预计算结果来表达查询。 @@ -326,7 +460,6 @@ JOIN 改写指的是查询和物化使用的表相同,可以在物化视图和 CREATE MATERIALIZED VIEW mv2 BUILD IMMEDIATE REFRESH AUTO ON SCHEDULE EVERY 1 hour DISTRIBUTED BY RANDOM BUCKETS 3 -PROPERTIES ('replication_num' = '1') AS SELECT t1.l_linenumber, o_custkey, @@ -351,7 +484,7 @@ WHERE l_linenumber > 1 and o_orderdate = '2023-10-18'; 当查询和物化视图的 JOIN 类型不一致时,如果物化视图能够提供查询所需的所有数据,那么通过在 JOIN 的外部补偿谓词,也可以进行透明改写。 -举例如下: +例如: **1. 物化视图定义:** @@ -359,7 +492,6 @@ WHERE l_linenumber > 1 and o_orderdate = '2023-10-18'; CREATE MATERIALIZED VIEW mv3 BUILD IMMEDIATE REFRESH AUTO ON SCHEDULE EVERY 1 hour DISTRIBUTED BY RANDOM BUCKETS 3 -PROPERTIES ('replication_num' = '1') AS SELECT l_shipdate, l_suppkey, o_orderdate, @@ -399,7 +531,7 @@ o_orderdate; 当查询和物化视图定义中的 group 维度一致时,如果物化视图使用的 group by 维度和查询的 group by 维度相同,并且查询使用的聚合函数可以使用物化视图的聚合函数来表示,那么可以进行透明改写。 -举例如下: +例如: 如下查询可以进行透明改写,因为查询和物化视图使用的聚合维度一致,可以使用物化视图 `o_shippriority` 字段进行过滤结果。查询中的 group by 维度和聚合函数可以使用物化视图的 group by 维度和聚合函数来改写。 @@ -409,7 +541,6 @@ o_orderdate; CREATE MATERIALIZED VIEW mv4 BUILD IMMEDIATE REFRESH AUTO ON SCHEDULE EVERY 1 hour DISTRIBUTED BY RANDOM BUCKETS 3 -PROPERTIES ('replication_num' = '1') AS SELECT o_shippriority, o_comment, @@ -447,7 +578,7 @@ o_comment; 在查询和物化视图定义中,即使聚合的维度不一致,也可以进行改写。物化视图使用的 `group by` 维度需要包含查询的 `group by` 维度,而查询可以没有 `group by`。并且,查询使用的聚合函数可以用物化视图的聚合函数来表示。 -举例如下: +例如: 以下查询可以进行透明改写。查询和物化视图使用的聚合维度不一致,但物化视图使用的维度包含了查询的维度。查询可以使用维度中的字段对结果进行过滤。查询会尝试使用物化视图 `SELECT` 后的函数进行上卷,例如,物化视图的 `bitmap_union` 最后会上卷成 `bitmap_union_count`,这和查询中的 `count(distinct)` 的语义保持一致。 @@ -457,7 +588,6 @@ o_comment; CREATE MATERIALIZED VIEW mv5 BUILD IMMEDIATE REFRESH AUTO ON SCHEDULE EVERY 1 hour DISTRIBUTED BY RANDOM BUCKETS 3 -PROPERTIES ('replication_num' = '1') AS SELECT l_shipdate, o_orderdate, l_partkey, l_suppkey, @@ -495,22 +625,23 @@ l_suppkey; 目前支持的聚合上卷函数列表如下: -| 查询中函数 | 物化视图中函数 | 函数上卷后 | -| ----------------------------------------------------- | -------------------------- | ------------------ | -| max | max | max | -| min | min | min | -| sum | sum | sum | -| count | count | sum | -| count(distinct) | bitmap_union | bitmap_union_count | -| bitmap_union | bitmap_union | bitmap_union | -| bitmap_union_count | bitmap_union | bitmap_union_count | -| hll_union_agg, approx_count_distinct, hll_cardinality | hll_union 或者 hll_raw_agg | hll_union_agg | +| 查询中函数 | 物化视图中函数 | 函数上卷后 | +|-------------------------------------------------------|------------------------------------------| ------------------ | +| max | max | max | +| min | min | min | +| sum | sum | sum | +| count | count | sum | +| count(distinct) | bitmap_union | bitmap_union_count | +| bitmap_union | bitmap_union | bitmap_union | +| bitmap_union_count | bitmap_union | bitmap_union_count | +| hll_union_agg, approx_count_distinct, hll_cardinality | hll_union 或者 hll_raw_agg | hll_union_agg | +| any_value | any_value 或者 select 后有any_value使用的列 | any_value | ### 多维聚合改写 支持多维聚合的透明改写,即如果物化视图中没有使用 `GROUPING SETS`, `CUBE`, `ROLLUP`,而查询中有多维聚合,并且物化视图 `group by` 后的字段包含查询中多维聚合的所有字段,那么也可以进行透明改写。 -举例如下: +例如: **1. 物化视图定义:** @@ -518,7 +649,6 @@ l_suppkey; CREATE MATERIALIZED VIEW mv5_1 BUILD IMMEDIATE REFRESH AUTO ON SCHEDULE EVERY 1 hour DISTRIBUTED BY RANDOM BUCKETS 3 -PROPERTIES ('replication_num' = '1') AS select o_orderstatus, o_orderdate, o_orderpriority, sum(o_totalprice) as sum_total, @@ -547,7 +677,7 @@ GROUPING SETS ((o_orderstatus, o_orderdate), (o_orderpriority), (o_orderstatus), 当分区物化视图不足以提供查询的所有数据时,可以使用 `union all` 的方式,将查询原表和物化视图的数据 `union all` 作为最终返回结果。 -举例如下: +例如: **1. 物化视图定义:** @@ -556,7 +686,6 @@ CREATE MATERIALIZED VIEW mv7 BUILD IMMEDIATE REFRESH AUTO ON MANUAL partition by(l_shipdate) DISTRIBUTED BY RANDOM BUCKETS 2 -PROPERTIES ('replication_num' = '1') as select l_shipdate, o_orderdate, l_partkey, l_suppkey, sum(o_totalprice) as sum_total @@ -615,7 +744,7 @@ group by 物化视图的定义 SQL 可以使用物化视图,此物化视图称为嵌套物化视图。嵌套的层数理论上没有限制,此物化视图既可以直查,也可以进行透明改写。嵌套物化视图同样可以参与透明改写。 -举例如下: +例如: **1. 创建内层物化视图 `mv8_0_inner_mv`:** @@ -623,7 +752,6 @@ group by CREATE MATERIALIZED VIEW mv8_0_inner_mv BUILD IMMEDIATE REFRESH COMPLETE ON MANUAL DISTRIBUTED BY RANDOM BUCKETS 2 -PROPERTIES ('replication_num' = '1') AS select l_linenumber, @@ -674,7 +802,7 @@ where o_orderstatus = 'o' 2. 嵌套物化视图透明改写默认关闭,开启方式见下面的开关设置。 -## Explain 查询透明改写情况 +### Explain 查询透明改写情况 查询透明改写命中情况,用于查看和调试。 @@ -713,16 +841,267 @@ explain <query_sql> explain memo plan <query_sql> ``` -## 附录 -### 物化视图相关开关介绍 +## 维护物化视图 + +### 权限说明 + +- 暂停/恢复/取消/刷新物化视图:需要具有物化视图的创建权限 。 + +### 刷新物化视图 + +物化视图是按照分区为单位进行刷新的。如果物化视图没有指定分区,那么每次都刷新物化视图的默认分区,即刷新物化视图的全部数据。 +物化视图有三种触发刷新机制: + +#### 1. 手动触发 + +用户通过 SQL 语句触发物化视图的刷新,目前有三种策略: + +- 检测基表的分区数据自上次刷新后是否有变化,刷新数据变化的分区,要求刷新完成后,物化视图的数据和基表保持同步。 + + ```sql + REFRESH MATERIALIZED VIEW mvName AUTO; + ``` + +- 不校验基表的分区数据自上次刷新后是否有变化,直接刷新物化视图的所有分区。 + + ```sql + REFRESH MATERIALIZED VIEW mvName COMPLETE; + ``` + +- 只刷新指定的分区。 + + ```sql + REFRESH MATERIALIZED VIEW mvName partitions(partitionName1,partitionName2); + ``` + +:::tip 提示 +`partitionName` 可以通过 `SHOW PARTITIONS FROM mvName` 获取。 +从 2.1.3 版本开始支持 Hive 检测基表的分区数据自上次刷新后是否有变化,其他外表暂时还不支持。内表一直支持。 +::: + +#### 2. 定时触发 + +通过物化视图的创建语句指定间隔多久刷新一次数据 + +- 如果物化视图的创建语句如下,要求全量刷新 (`REFRESH COMPLETE`),那么物化视图每 10 小时刷新一次,并且刷新物化视图的所有分区。 + + ```sql + CREATE MATERIALIZED VIEW mv_6 + REFRESH COMPLETE ON SCHEDULE EVERY 10 hour + AS + SELECT * FROM lineitem; + ``` + +- 如果物化视图的创建语句如下,要求自动计算需要刷新的分区 (`REFRESH AUTO`),那么物化视图每 10 小时刷新一次(从 2.1.3 版本开始能自动计算 Hive 需要刷新的分区)。 + + ```sql + CREATE MATERIALIZED VIEW mv_7 + REFRESH AUTO ON SCHEDULE EVERY 10 hour + PARTITION by(l_shipdate) + AS + SELECT * FROM lineitem; + ``` + +#### 3. 自动触发 + +:::tip 提示 +自 Apache Doris 2.1.4 版本起支持此功能。 +::: + +基表数据发生变更后,自动触发相关物化视图刷新,刷新的分区范围与“定时触发”一致。 + +如果物化视图的创建语句如下,那么当 `t1` 的数据发生变化时,会自动触发物化视图的刷新。 + +```sql +CREATE MATERIALIZED VIEW mv_8 + REFRESH AUTO ON COMMIT + PARTITION by(l_shipdate) + AS +SELECT * FROM lineitem; +``` + +详情参考 [REFRESH MATERIALIZED VIEW](../../../sql-manual/sql-statements/Utility-Statements/REFRESH-MATERIALIZED-VIEW/) + +### 暂停物化视图 + +详情参考 [PAUSE MATERIALIZED VIEW](../../../sql-manual/sql-statements/Utility-Statements/PAUSE-MATERIALIZED-VIEW) + +### 启用物化视图 + +详情参考 [RESUME MATERIALIZED VIEW](../../../sql-manual/sql-statements/Utility-Statements/RESUME-MATERIALIZED-VIEW) + +### 取消物化视图刷新任务 + +详情参考 [CANCEL MATERIALIZED VIEW TASK](../../../sql-manual/sql-statements/Utility-Statements/CANCEL-MATERIALIZED-VIEW-TASK) + +### 元数据查询 + +#### 查询物化视图信息 + +```sql +SELECT * +FROM mv_infos('database'='db_name') +WHERE Name = 'mv_name' \G +``` + +返回结果如下: +```sql +*************************** 1. row *************************** + Id: 139570 + Name: mv11 + JobName: inner_mtmv_139570 + State: NORMAL +SchemaChangeDetail: + RefreshState: SUCCESS + RefreshInfo: BUILD IMMEDIATE REFRESH AUTO ON MANUAL + QuerySql: SELECT l_shipdate, l_orderkey, O_ORDERDATE, count(*) +FROM lineitem +LEFT OUTER JOIN orders on l_orderkey = o_orderkey +GROUP BY l_shipdate, l_orderkey, O_ORDERDATE + EnvInfo: EnvInfo{ctlId='0', dbId='16813'} + MvProperties: {} + MvPartitionInfo: MTMVPartitionInfo{partitionType=FOLLOW_BASE_TABLE, relatedTable=lineitem, relatedCol='l_shipdate', partitionCol='l_shipdate'} +SyncWithBaseTables: 1 +``` + +- **SyncWithBaseTables:** 表示物化视图和基表的数据是否一致。 + + - 对于全量构建的物化视图,此字段为 1,表明此物化视图可用于透明改写。 + + - 对于分区增量的物化视图,分区物化视图是否可用,是以分区粒度去看的。也就是说,即使物化视图的部分分区不可用,但只要查询的是有效分区,那么此物化视图依旧可用于透明改写。是否能透明改写,主要看查询所用分区的 `SyncWithBaseTables` 字段是否一致。如果 `SyncWithBaseTables` 是 1,此分区可用于透明改写;如果是 0,则不能用于透明改写。 + +- **JobName:** 物化视图构建 Job 的名称,每个物化视图有一个 Job,每次刷新会有一个新的 Task,Job 和 Task 是 1:n 的关系 + +- **State:** 如果变为 SCHEMA_CHANGE,代表基表的 Schema 发生了变化,此时物化视图将不能用来透明改写 (但是不影响直接查询物化视图),下次刷新任务如果执行成功,将恢复为 NORMAL。 + +- **SchemaChangeDetail:** 表示 SCHEMA_CHANGE 发生的原因。 + +- **RefreshState:** 物化视图最后一次任务刷新的状态。如果为 FAIL,代表执行失败,可以通过 `tasks() `命令进一步定位失败原因。Task 命令见本文[查看物化视图 Task 状态](#查看物化视图-task-状态)。 + +- **SyncWithBaseTables:** 是否和基表数据同步。1 为同步,0 为不同步。如果不同步,可通过 `show partitions` 进一步判断哪个分区不同步。`show partitions` 见下文分区物化视图查看 SyncWithBaseTables 状态方法。 + +对于透明改写,通常物化视图会出现两种状态: + +- **状态正常:** 指的是当前物化视图是否可用于透明改写。 + +- **不可用、状态不正常:** 指的是物化视图不能用于透明改写的简称。尽管如此,该物化视图还是可以直查的。 + + +详情参考 [MV_INFOS](../../../sql-manual/sql-functions/table-valued-functions/mv-infos) + + +#### 查询刷新任务 TASK 信息 + +每个物化视图有一个 Job,每次刷新会有一个新的 Task,Job 和 Task 是 1:n 的关系。 +根据物化视图名称查看物化视图的 Task 状态,运行如下语句,可以查看刷新任务的状态和进度: + +```sql +SELECT * +FROM tasks("type"="mv") +WHERE mvName = 'mv_name' +ORDER BY CreateTime DESC \G +``` + +返回结果如下: + +```sql +*************************** 1. row *************************** + TaskId: 167019363907545 + JobId: 139872 + JobName: inner_mtmv_139570 + MvId: 139570 + MvName: mv11 + MvDatabaseId: 16813 + MvDatabaseName: regression_test_nereids_rules_p0_mv + Status: SUCCESS + ErrorMsg: + CreateTime: 2024-06-21 10:31:43 + StartTime: 2024-06-21 10:31:43 + FinishTime: 2024-06-21 10:31:45 + DurationMs: 2466 + TaskContext: {"triggerMode":"SYSTEM","isComplete":false} + RefreshMode: COMPLETE +NeedRefreshPartitions: ["p_20231023_20231024","p_20231019_20231020","p_20231020_20231021","p_20231027_20231028","p_20231030_20231031","p_20231018_20231019","p_20231024_20231025","p_20231021_20231022","p_20231029_20231030","p_20231028_20231029","p_20231025_20231026","p_20231022_20231023","p_20231031_20231101","p_20231016_20231017","p_20231026_20231027"] + CompletedPartitions: ["p_20231023_20231024","p_20231019_20231020","p_20231020_20231021","p_20231027_20231028","p_20231030_20231031","p_20231018_20231019","p_20231024_20231025","p_20231021_20231022","p_20231029_20231030","p_20231028_20231029","p_20231025_20231026","p_20231022_20231023","p_20231031_20231101","p_20231016_20231017","p_20231026_20231027"] + Progress: 100.00% (15/15) + LastQueryId: fe700ca3d6504521-bb522fc9ccf615e3 +``` + +- NeedRefreshPartitions,CompletedPartitions 记录的是此次 Task 刷新的分区。 + +- Status:如果为 FAILED,代表运行失败,可通过 ErrorMsg 查看失败原因,也可通过 LastQueryId 来搜索 Doris 的日志,获取更详细的错误信息。目前任务失败会导致已有物化视图不可用,后面会改成尽管任务失败,但是已存在的物化视图可用于透明改写。 + +- ErrorMsg:失败原因。 + +- RefreshMode:COMPLETE 代表刷新了全部分区,PARTIAL 代表刷新了部分分区,NOT_REFRESH 代表不需要刷新任何分区。 + +:::info 备注 +- 如果物化视图创建的时候设置了 `grace_period` 属性,那么即使 `SyncWithBaseTables` 是 false 或者 0,有些情况下它依然可用于透明改写。 + +- `grace_period` 的单位是秒,指的是容许物化视图和所用基表数据不一致的时间。 + +- 如果设置成 0,意味着要求物化视图和基表数据保持一致,此物化视图才可用于透明改写。 + +- 如果设置成 10,意味着物化视图和基表数据允许 10 秒的延迟,如果物化视图的数据和基表的数据有延迟,在 10 秒内,此物化视图都可以用于透明改写。 + ::: +详情参考 [TASKS](../../../sql-manual/sql-functions/table-valued-functions/tasks?_highlight=task) + + +#### 查询物化视图对应的 JOB + +```sql +SELECT * +FROM jobs("type"="mv") +WHERE Name="inner_mtmv_75043"; +``` + +详情参考 [JOBS](../../../sql-manual/sql-functions/table-valued-functions/jobs) + + +#### 查询物化视图的分区信息: + +**分区物化视图查看 SyncWithBaseTables 状态方法** + +运行 `show partitions from mv_name`查看查询使用的分区是否有效,返回结果如下: + +```Plain +show partitions from mv11; ++-------------+---------------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+ +| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable | SyncWithBaseTables | UnsyncTables | ++-------------+---------------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+ +| 140189 | p_20231016_20231017 | 1 | 2024-06-21 10:31:45 | NORMAL | l_shipdate | [types: [DATEV2]; keys: [2023-10-16]; ..types: [DATEV2]; keys: [2023-10-17]; ) | l_orderkey | 10 | 1 | HDD | 9999-12-31 23:59:59 | | NULL | 0.000 | false | tag.location.default: 1 | true | true | [] | +| 139995 | p_20231018_20231019 | 2 | 2024-06-21 10:31:44 | NORMAL | l_shipdate | [types: [DATEV2]; keys: [2023-10-18]; ..types: [DATEV2]; keys: [2023-10-19]; ) | l_orderkey | 10 | 1 | HDD | 9999-12-31 23:59:59 | | NULL | 880.000 B | false | tag.location.default: 1 | true | true | [] | +| 139898 | p_20231019_20231020 | 2 | 2024-06-21 10:31:43 | NORMAL | l_shipdate | [types: [DATEV2]; keys: [2023-10-19]; ..types: [DATEV2]; keys: [2023-10-20]; ) | l_orderkey | 10 | 1 | HDD | 9999-12-31 23:59:59 | | NULL | 878.000 B | false | tag.location.default: 1 | true | true | [] | ++-------------+---------------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+ +``` + +主要查看 `SyncWithBaseTables` 字段是否为 true。false 表示此分区不可用于透明改写。 + +详情参考 [SHOW PARTITIONS](../../../sql-manual/sql-statements/Show-Statements/SHOW-PARTITIONS) + + +#### 查看物化视图表结构 + +详情参考 [DESCRIBE](../../../sql-manual/sql-statements/Utility-Statements/DESCRIBE) + +### 相关配置 +#### Session Variables 开关 + +| 开关 | 说明 | +|------------------------------------------------------------------------------| ------------------------------------------------------------ | +| SET enable_nereids_planner = true; | 异步物化视图只有在新优化器下才支持,所以物化视图透明改写没有生效时,需要开启新优化器 | +| SET enable_materialized_view_rewrite = true; | 开启或者关闭查询透明改写,默认开启 | +| SET materialized_view_rewrite_enable_contain_external_table = true; | 参与透明改写的物化视图是否允许包含外表,默认不允许,如果物化视图的定义 SQL 中包含外表,也想参与到透明改写,可以打开此开关。 | +| SET materialized_view_rewrite_success_candidate_num = 3; | 透明改写成功的结果集合,允许参与到 CBO 候选的最大数量,默认是 3。如果发现透明改写的性能很慢,可以考虑把这个值调小。 | +| SET enable_materialized_view_union_rewrite = true; | 当分区物化视图不足以提供查询的全部数据时,是否允许基表和物化视图 union all 来响应查询,默认允许。如果发现命中物化视图时数据错误,可以把此开关关闭。 | +| SET enable_materialized_view_nest_rewrite = true; | 是否允许嵌套改写,默认不允许。如果查询 SQL 很复杂,需要构建嵌套物化视图才可以命中,那么需要打开此开关。 | +| SET materialized_view_relation_mapping_max_count = 8; | 透明改写过程中,relation mapping 最大允许数量,如果超过,进行截取。relation mapping 通常由表自关联产生,数量一般会是笛卡尔积,比如 3 张表,可能会产生 8 种组合。默认是 8。如果发现透明改写时间很长,可以把这个值调低 | +| SET enable_dml_materialized_view_rewrite = true; | DML 时, 是否开启基于结构信息的物化视图透明改写 | +| SET enable_dml_materialized_view_rewrite_when_base_table_unawareness = true; | DML 时,当物化视图存在无法实时感知数据的外表时,是否开启基于结构信息的物化视图透明改写 | + +#### fe.conf 配置 +- **job_mtmv_task_consumer_thread_num:** 此参数控制同时运行的物化视图刷新任务数量,默认是10,超过这个数量的任务将处于pending状态 +修改这个参数需要重启 fe 才可以生效。 + -| 开关 | 说明 | -| ------------------------------------------------------------ | ------------------------------------------------------------ | -| SET enable_nereids_planner = true; | 异步物化视图只有在新优化器下才支持,所以物化视图透明改写没有生效时,需要开启新优化器 | -| SET enable_materialized_view_rewrite = true; | 开启或者关闭查询透明改写,默认开启 | -| SET materialized_view_rewrite_enable_contain_external_table = true; | 参与透明改写的物化视图是否允许包含外表,默认不允许,如果物化视图的定义 SQL 中包含外表,也想参与到透明改写,可以打开此开关。 | -| SET materialized_view_rewrite_success_candidate_num = 3; | 透明改写成功的结果集合,允许参与到 CBO 候选的最大数量,默认是 3。如果发现透明改写的性能很慢,可以考虑把这个值调小。 | -| SET enable_materialized_view_union_rewrite = true; | 当分区物化视图不足以提供查询的全部数据时,是否允许基表和物化视图 union all 来响应查询,默认允许。如果发现命中物化视图时数据错误,可以把此开关关闭。 | -| SET enable_materialized_view_nest_rewrite = true; | 是否允许嵌套改写,默认不允许。如果查询 SQL 很复杂,需要构建嵌套物化视图才可以命中,那么需要打开此开关。 | -| SET materialized_view_relation_mapping_max_count = 8; | 透明改写过程中,relation mapping 最大允许数量,如果超过,进行截取。relation mapping 通常由表自关联产生,数量一般会是笛卡尔积,比如 3 张表,可能会产生 8 种组合。默认是 8。如果发现透明改写时间很长,可以把这个值调低 | \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/overview.md index a140b4a8718..71853418b87 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/overview.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/overview.md @@ -1,6 +1,6 @@ --- { - "title": "异步物化视图原理介绍", + "title": "异步物化视图概述", "language": "zh-CN" } --- @@ -24,518 +24,82 @@ specific language governing permissions and limitations under the License. --> -## 异步物化视图构建 +物化视图作为一种高效的解决方案,兼具了视图的灵活性和物理表的高性能优势。 +它能够预先计算并存储查询的结果集,从而在查询请求到达时,直接从已存储的物化视图中快速获取结果,避免了重新执行复杂的查询语句所带来的开销。 -物化视图创建分区有两种方式:自定义分区和依赖基表的分区自动创建分区 +## 使用场景 -### 自定义分区 +- 查询加速与并发提升:物化视图能够显著提高查询速度,同时增强系统的并发处理能力,有效减少资源消耗。 +- 简化ETL流程:在数据抽取、转换和加载(ETL)过程中,物化视图能够简化流程,提升开发效率,使数据处理更加顺畅。 +- 加速湖仓一体架构中的外表查询:在湖仓一体架构中,物化视图能够显著提升对外部数据源的查询速度,提高数据访问效率。 +- 提升写入效率:通过减少资源竞争,物化视图能够优化数据写入过程,提高写入效率,确保数据的一致性和完整性。 -创建物化视图时,如果不指定分区信息,物化视图将默认创建一个分区,所有数据都存放在这个分区中。 +## 使用限制 +- 异步物化视图与基表数据一致性:异步物化视图与基表的数据最终会保持一致,但无法实时同步,即无法保持实时一致性。 +- 窗口函数查询支持:当前,如果查询中包含了窗口函数,暂不支持将该查询透明地改写为利用物化视图的形式。 +- 包含ORDER BY的物化视图与查询:若物化视图本身包含了ORDER BY子句,则系统暂不支持将该物化视图用于透明改写查询。但请注意,查询本身仍然可以包含ORDER BY子句。 +- 物化视图连接表多于查询表:如果物化视图所连接的表数量多于查询所涉及的表(例如,查询仅涉及t1和t2,而物化视图则包含了t1、t2以及额外的t3), +则系统目前不支持将该查询透明地改写为利用该物化视图的形式。 -### 依赖基表进行分区 +## 原理介绍 -物化视图可以通过多个基表 JOIN 关联创建,并可以选择追随其中一个基表进行分区(建议选择事实表)。 +物化视图,作为数据库中的一种高级特性,其实质为类型MTMV的内表。在创建物化视图时,系统会同时注册一个刷新任务。此任务会在需要时运行,执行INSERT OVERWRITE语句,以将最新的数据写入物化视图中。 -例如,基表`t1`和`t2`的建表语句分别如下: +**刷新机制** +与同步物化视图所采用的实时增量刷新不同,异步物化视图提供了更为灵活的刷新选项 -```sql -CREATE TABLE `t1` ( - `user_id` LARGEINT NOT NULL, - `o_date` DATE NOT NULL, - `num` SMALLINT NOT NULL -) ENGINE=OLAP -COMMENT 'OLAP' -PARTITION BY RANGE(`o_date`) -( -PARTITION p20170101 VALUES [('2017-01-01'), ('2017-01-02')), -PARTITION p20170102 VALUES [('2017-01-02'), ('2017-01-03')), -PARTITION p20170201 VALUES [('2017-02-01'), ('2017-02-02')) -) -DISTRIBUTED BY HASH(`user_id`) BUCKETS 2 -PROPERTIES ('replication_num' = '1') ; -CREATE TABLE `t2` ( - `user_id` LARGEINT NOT NULL, - `age` SMALLINT NOT NULL -) ENGINE=OLAP -PARTITION BY LIST(`age`) -( - PARTITION `p1` VALUES IN ('1'), - PARTITION `p2` VALUES IN ('2') -) -DISTRIBUTED BY HASH(`user_id`) BUCKETS 2 -PROPERTIES ('replication_num' = '1') ; -``` +**全量刷新:** +在此模式下,系统会重新计算物化视图定义SQL所涉及的所有数据,并将结果完整地写入物化视图。 +此过程确保了物化视图中的数据与基表数据保持一致,但可能会消耗更多的计算资源和时间。 -若物化视图的建表语句如下: +**分区增量刷新:** +当物化视图的基表分区数据发生变化时,系统能够智能地识别出这些变化,并仅针对受影响的分区进行刷新。 +这种机制显著降低了刷新物化视图所需的计算资源和时间,同时保证了数据的最终一致性。 -```sql -CREATE MATERIALIZED VIEW mv1 -BUILD DEFERRED REFRESH AUTO ON MANUAL -partition by(`order_date`) -DISTRIBUTED BY RANDOM BUCKETS 2 -PROPERTIES ( -'replication_num' = '1' -) -AS -SELECT t1.o_date as order_date, t1.user_id as user_id, t1.num, t2.age FROM t1 join t2 on t1.user_id=t2.user_id; -``` +**透明改写:** +透明改写是数据库优化查询性能的一种重要手段。在处理用户查询时,系统能够自动对SQL进行优化和改写, +以提高查询的执行效率和降低计算成本。这一改写过程对用户而言是透明的,无需用户进行任何干预。 -那么物化视图`mv1`将和`t1`一样,有三个分区: +Doris异步物化视图采用了基于SPJG(SELECT-PROJECT-JOIN-GROUP-BY)模式的透明改写算法。 +该算法能够深入分析SQL的结构信息,自动寻找并选择合适的物化视图进行透明改写。在多个物化视图可供选择时, +算法还会根据一定的策略(如成本模型)选择最优的物化视图来响应查询SQL,从而进一步提升查询性能。 -- `[('2017-01-01'), ('2017-01-02'))` -- `[('2017-01-02'), ('2017-01-03'))` +## 物化刷新数据湖支持情况 -- `[('2017-02-01'), ('2017-02-02'))` +对于物化刷新数据湖的支持情况,不同类型的表和 Catalog 有不同的支持程度: -若物化视图的建表语句如下: +| 表类型 | Catalog 类型 | 全量刷新 | 分区刷新 | 触发刷新 | +| ------- |----------------|--------| -------- |----------| +| 内表 | Internal | 2.1 支持 | 2.1 支持 | 2.1.4 支持 | +| Hive | Hive | 2.1 支持 | 2.1 支持 | 不支持 | +| Iceberg | Iceberg | 2.1 支持 | 不支持 | 不支持 | +| Paimon | Paimon | 2.1 支持 | 不支持 | 不支持 | +| Hudi | Hudi | 2.1 支持 | 不支持 | 不支持 | +| JDBC | JDBC | 2.1 支持 | 不支持 | 不支持 | +| ES | ES | 2.1 支持 | 不支持 | 不支持 | -```sql -CREATE MATERIALIZED VIEW mv2 -BUILD DEFERRED REFRESH AUTO ON MANUAL -partition by(`age`) -DISTRIBUTED BY RANDOM BUCKETS 2 -PROPERTIES ( -'replication_num' = '1' -) -AS -SELECT t1.o_date as order_date, t1.user_id as user_id, t1.num, t2.age FROM t1 join t2 on t1.user_id=t2.user_id; -``` +## 物化视图和 OLAP 内表关系 -那么物化视图`mv2`将和`t2`一样,有两个分区: - -- `('1')` - -- `('2')` - -在依赖基表分区创建物化视图时,不同场景需要合理设计不同的分区策略,下面将举例说明多列分区、部分分区与分区上卷三种情况。 - -**1. 基表有多列分区** - -:::tip 提示 -自 Doris 2.1.0 版本起支持多列分区 -::: - -目前仅支持 Hive 外表有多列分区。Hive 外表有很多多级分区的情况,例如一级分区按照日期,二级分区按照区域。物化视图可以选择 Hive 的某一级分区列作为物化视图的分区列。 - -例如,Hive 的建表语句如下: - -```sql -CREATE TABLE hive1 ( -`k1` int) -PARTITIONED BY ( -`year` int, -`region` string) -STORED AS ORC; - -alter table hive1 add if not exists -partition(year=2020,region="bj") -partition(year=2020,region="sh") -partition(year=2021,region="bj") -partition(year=2021,region="sh") -partition(year=2022,region="bj") -partition(year=2022,region="sh") -``` - -当物化视图的创建语句如下时,物化视图`mv_hive`将有三个分区:`('2020'),('2021'),('2022')` - -```sql -CREATE MATERIALIZED VIEW mv_hive -BUILD DEFERRED REFRESH AUTO ON MANUAL -partition by(`year`) -DISTRIBUTED BY RANDOM BUCKETS 2 -PROPERTIES ('replication_num' = '1') -AS -SELECT k1,year,region FROM hive1; -``` - -当物化视图的建表语句如下时,那么物化视图`mv_hive2`将有如下两个分区:`('bj')`,`('sh')`: - -```sql -CREATE MATERIALIZED VIEW mv_hive2 -BUILD DEFERRED REFRESH AUTO ON MANUAL -partition by(`region`) -DISTRIBUTED BY RANDOM BUCKETS 2 -PROPERTIES ('replication_num' = '1') -AS -SELECT k1,year,region FROM hive1; -``` - -**2. 仅使用基表部分分区** - -:::tip 提示 -自 Doris 2.1.1 版本起支持此功能 +:::tips +自 2.1.4 版本起,物化视图支持 Duplicate 模型 ::: -有些基表有很多分区,但是物化视图只关注最近一段时间的“热”数据,那么可以使用此功能。 - -基表的建表语句如下: - -```sql -CREATE TABLE t1 ( - `k1` INT, - `k2` DATE NOT NULL -) ENGINE=OLAP -DUPLICATE KEY(`k1`) -COMMENT 'OLAP' -PARTITION BY range(`k2`) -( -PARTITION p26 VALUES [("2024-03-26"),("2024-03-27")), -PARTITION p27 VALUES [("2024-03-27"),("2024-03-28")), -PARTITION p28 VALUES [("2024-03-28"),("2024-03-29")) -) -DISTRIBUTED BY HASH(`k1`) BUCKETS 2 -PROPERTIES ( -'replication_num' = '1' -); -``` - -物化视图的创建语句如以下举例,代表物化视图只关注最近一天的数据。若当前时间为 2024-03-28 xx:xx:xx,这样物化视图会仅有一个分区 `[("2024-03-28"),("2024-03-29")]`: - -```sql -CREATE MATERIALIZED VIEW mv1 -BUILD DEFERRED REFRESH AUTO ON MANUAL -partition by(`k2`) -DISTRIBUTED BY RANDOM BUCKETS 2 -PROPERTIES ( -'replication_num' = '1', -'partition_sync_limit'='1', -'partition_sync_time_unit'='DAY' -) -AS -SELECT * FROM t1; -``` - -若时间又过了一天,当前时间为` 2024-03-29 xx:xx:xx`,`t1`则会新增一个分区 `[("2024-03-29"),("2024-03-30")]`,若此时刷新物化视图,刷新完成后,物化视图会仅有一个分区 `[("2024-03-29"),("2024-03-30")]`。 - -此外,分区字段是字符串类型时,可以设置物化视图属性 `partition_date_format`,例如 `%Y-%m-%d` 。 - -**3. 分区上卷** - -:::tip 提示 -自 Doris 2.1.5 版本起支持此功能 -::: - -当基表数据经过聚合处理后,各分区的数据量可能会显著减少。在这种情况下,可以采用分区上卷策略,以降低物化视图的分区数量。 - -- List 分区 - - 需要注意的是,Hive 中的分区对应于 Doris 中的 list 分区。 - - 假设基表的建表语句如下: - - ```sql - CREATE TABLE `t1` ( - `k1` INT NOT NULL, - `k2` DATE NOT NULL - ) ENGINE=OLAP - DUPLICATE KEY(`k1`) - COMMENT 'OLAP' - PARTITION BY list(`k2`) - ( - PARTITION p_20200101 VALUES IN ("2020-01-01"), - PARTITION p_20200102 VALUES IN ("2020-01-02"), - PARTITION p_20200201 VALUES IN ("2020-02-01") - ) - DISTRIBUTED BY HASH(`k1`) BUCKETS 2 - PROPERTIES ('replication_num' = '1') ; - ``` - - 若物化视图的创建语句如下,则该物化视图将包含两个分区:`("2020-01-01","2020-01-02")` 和 `("2020-02-01")` - - ```sql - CREATE MATERIALIZED VIEW mv1 - BUILD DEFERRED REFRESH AUTO ON MANUAL - partition by (date_trunc(`k2`,'month')) - DISTRIBUTED BY RANDOM BUCKETS 2 - PROPERTIES ( - 'replication_num' = '1' - ) - AS - SELECT * FROM t1; - ``` - - 若物化视图的创建语句如下,则该物化视图将只包含一个分区:`("2020-01-01","2020-01-02","2020-02-01")` - - ```sql - CREATE MATERIALIZED VIEW mv1 - BUILD DEFERRED REFRESH AUTO ON MANUAL - partition by (date_trunc(`k2`,'year')) - DISTRIBUTED BY RANDOM BUCKETS 2 - PROPERTIES ( - 'replication_num' = '1' - ) - AS - SELECT * FROM t1; - ``` - -- Range 分区 - - 假设基表的建表语句如下: - - ```sql - CREATE TABLE `t1` ( - `k1` LARGEINT NOT NULL, - `k2` DATE NOT NULL - ) ENGINE=OLAP - DUPLICATE KEY(`k1`) - COMMENT 'OLAP' - PARTITION BY range(`k2`) - ( - PARTITION p_20200101 VALUES [("2020-01-01"),("2020-01-02")), - PARTITION p_20200102 VALUES [("2020-01-02"),("2020-01-03")), - PARTITION p_20200201 VALUES [("2020-02-01"),("2020-02-02")) - ) - DISTRIBUTED BY HASH(`k1`) BUCKETS 2 - PROPERTIES ('replication_num' = '1') ; - ``` - - 若物化视图的创建语句如下,则该物化视图将包含两个分区:`[("2020-01-01","2020-02-01")] `和` [("2020-02-01","2020-03-01")]` - - ```sql - CREATE MATERIALIZED VIEW mv1 - BUILD DEFERRED REFRESH AUTO ON MANUAL - partition by (date_trunc(`k2`,'month')) - DISTRIBUTED BY RANDOM BUCKETS 2 - PROPERTIES ( - 'replication_num' = '1' - ) - AS - SELECT * FROM t1; - ``` - - 若物化视图的创建语句如下,则该物化视图将只包含一个分区:`[("2020-01-01","2021-01-01")]` - - ```sql - CREATE MATERIALIZED VIEW mv1 - BUILD DEFERRED REFRESH AUTO ON MANUAL - partition by (date_trunc(`k2`,'year')) - DISTRIBUTED BY RANDOM BUCKETS 2 - PROPERTIES ( - 'replication_num' = '1' - ) - AS - SELECT * FROM t1; - ``` - - 此外,如果分区字段为字符串类型,可以通过设置物化视图的 `partition_date_format` 属性来指定日期格式,例如 `'%Y-%m-%d'`。 - -## 异步物化视图刷新 - -物化视图是按照分区为单位进行刷新的。如果物化视图没有指定分区,那么每次都刷新物化视图的默认分区,即刷新物化视图的全部数据。 - -物化视图有三种触发刷新机制: - -### 手动触发 - -用户通过 SQL 语句触发物化视图的刷新,目前有三种策略: - -- 不关心具体刷新哪些分区,要求刷新完成后,物化视图的数据和基表保持同步。 - - ```sql - REFRESH MATERIALIZED VIEW mvName AUTO; - ``` - -- 不管物化视图现存哪些数据,刷新物化视图的所有分区。 - - ```sql - REFRESH MATERIALIZED VIEW mvName COMPLETE; - ``` - -- 不管物化视图现存哪些数据,只刷新指定的分区。 - - ```sql - REFRESH MATERIALIZED VIEW mvName partitions(partitionName1,partitionName2); - ``` - -:::tip 提示 -`partitionName` 可以通过 `SHOW PARTITIONS FROM mvName` 获取。 -::: - -### 定时触发 - -通过物化视图的创建语句指定间隔多久刷新一次数据 - -- 如果物化视图的创建语句如下,要求全量刷新 (`REFRESH COMPLETE`),那么物化视图每 10 小时刷新一次,并且刷新物化视图的所有分区。 - - ```sql - CREATE MATERIALIZED VIEW mv1 - REFRESH COMPLETE ON SCHEDULE EVERY 10 hour - partition by(`xxx`) - AS - select ...; - ``` - -- 如果物化视图的创建语句如下,要求自动计算需要刷新的分区 (`REFRESH AUTO`),那么物化视图每 10 小时刷新一次(从 2.1.3 版本开始能自动计算 Hive 需要刷新的分区)。 - - ```sql - CREATE MATERIALIZED VIEW mv1 - REFRESH AUTO ON SCHEDULE EVERY 10 hour - partition by(`xxx`) - AS - select ...; - ``` - -### 自动触发 - -:::tip 提示 -自 Apache Doris 2.1.4 版本起支持此功能。 -::: - -基表数据发生变更后,自动触发相关物化视图刷新,刷新的分区范围与“定时触发”一致。 - -如果物化视图的创建语句如下,那么当 `t1` 的数据发生变化时,会自动触发物化视图的刷新。 - -```sql -CREATE MATERIALIZED VIEW mv1 -REFRESH ON COMMIT -partition by(`xxx`) -AS -select ... from t1; -``` - -## 透明改写能力 - -Doris 的异步物化视图采用了基于 SPJG(SELECT-PROJECT-JOIN-GROUP-BY)模式的结构信息来进行透明改写的算法。Doris 能够分析查询 SQL 的结构信息,自动寻找满足要求的物化视图,并尝试进行透明改写,使用最优的物化视图来表达查询 SQL。 - -### 流程图 - - - -### 基于结构信息透明改写 - -如上述流程图所示,在获取物化对应的查询结构后,将基于结构信息进行透明改写。这时,需要做如下校验: - -**1. 校验物化视图是否包含查询所需的所有行** - -- 对于查询:`SELECT * FROM T1, T2, …, Tm WHERE Wq` - -- 对于物化视图:`SELECT * FROM T1, T2, …, Tm WHERE Wv` - -:::caution 注意 -查询的条件要强于或等于物化的条件。 -::: - -其中 T1, T2 是表、Wq 代表查询的 WHERE 过滤条件、Wv 代表物化视图 WHERE 过滤条件。要满足视图包含了查询所需要的所有行,就要满足过滤条件 Wq 能够推导出 Wv,即 `Wq -> Wv`(比如 `Wq > 20`, `Wv > 10`,Wq 就能够推导出 Wv。) - -对于表达式 W 还可以细化,过滤的表达式可以拆成三部分:PE ∧ PR ∧ PU。 - -- PE 代表相等的表达式; - -- PR 代表范围过滤的表达式,使用“<”, “≤”, “=”, “≥”, “>”连接的操作符; - -- PU 代表除了前面表达式的其余补偿表达式。 - -因此,基于 `Wq -> Wv` 推导出 `(PEq ∧ PRq ∧ PUq → PEv ∧ PRv ∧ PUv)`。其中 q 代表查询,v 代表物化视图。 - -因为 A -> C,那么 AB -> C,上面的表达式可以进一步推导如下: - -```Plain -(PEq∧ PRq∧PUq⇒ PEv )∧ -(PEq∧ PRq∧PUq⇒ PRv)∧ -(PEq∧ PRq∧PUq⇒ PUv) -``` - -可以进一步简化成: - -```Plain -(PEq ⇒ PEv ) (Equijoin subsumption test 等值条件校验) -(PEq ∧ PRq ⇒ PRv) (Range subsumption test 范围条件校验) -(PEq ∧ PUq ⇒ PUv ) (Residual subsumption test 补偿条件校验) -``` - -- 等值条件校验:总体原则是物化视图的相等表达式是查询相等表达式的子集。等价表达式具有传递性,也应保持正确性。 - -- 视图的范围表达式应包含查询的表达式。例如,T=常量值,可以转换成 T>= 常量值 and T<= 常量值的形式。 - -- 采用 Expression Equals 的方式,校验物化视图中出现的补偿表达式是否是查询补偿表达式的子集。 - -接下来,我们将通过举例进一步解释检验步骤: - -物化视图的定义: - -```sql -Select l_orderkey, o_custkey, l_partkey, -l_shipdate, o_orderdate, -l_quantity*l_extendedprice as gross_revenue -From dbo.lineitem, dbo.orders, dbo.part -Where l_orderkey = o_orderkey -And l_partkey = p_partkey -And p_partkey >= 150 -And o_custkey >= 50 and o_custkey <= 500 -And p_name like ‘%abc%’ -``` - -查询的定义: - -```sql -Select l_orderkey, o_custkey, l_partkey, -l_quantity*l_extendedprice -From lineitem, orders, part -Where l_orderkey = o_orderkey -And l_partkey = p_partkey -And l_partkey >= 150 and l_partkey <= 160 -And o_custkey = 123 -And o_orderdate = l_shipdate -And p_name like ‘%abc%’ -And l_quantity*l_extendedprice > 100 -``` - -第一步:计算等价类 - -- 视图等价类:`{l_orderkey, o_orderkey},{l_partkey, p_partkey}, {o_orderdate}, {l_shipdate}` - -- 查询等价类:`{l_orderkey, o_orderkey},{l_partkey, p_partkey}, {o_orderdate, l_shipdate}` - -第二步:校验等值等价类 - -- 若 视图等价表达式 = 查询等价表达式的子集,则通过校验。 - -第三步:计算范围表达式 - -- 视图范围表达式:`{l_partkey, p_partkey} ∈ (150, +∞), {o_custkey} ∈ (50, 500)` - -- 查询范围表达式: `{l_partkey, p_partkey} ∈ (150, 160), {o_custkey} ∈ (123, 123)` - -第四步:校验范围表达式 - -- 视图范围表达式:(150, 160) 在 (150, +∞) 范围内 - -- 查询范围表达式:(123, 123) 在 (50, 500) 范围内 - -第五步:校验补偿表达式 - -- 视图补偿表达式:p_name like‘%abc%’ - -- 查询补偿表达式:p_name like‘%abc%’ - -因为 `l_quantity*l_extendedprice > 100`,视图的补偿表达式是查询的子集。在经过以上步骤校验,可以保证所有的行从视图中获取,需要在视图上添加补偿条件,补偿条件如下: - -```sql -(o_orderdate = l_shipdate), -({p_partkey,l_partkey} <= 160), -(o_custkey = 123), and -(l_quantity*l_extendedprice > 100.00). -``` - -**2. 补偿的条件是否可以从物化视图获取** - -需要对视图添加补偿条件,才能保证最终获取的数据和原始查询一致。需要进行校验,验证补偿条件中选择的列或表达式可以从视图上获取。 - -即需要校验列 `o_orderdate`,`l_shipdate`,`p_partkey`,`{p_partkey, l_partkey}`,`o_custkey` 以及表达式 `l_quantity*l_extendedprice` 是否可从视图中获取。 - -**3. 表达式和列是否可从物化视图获取** - -与校验补偿条件相似,如果输出表达式是常量,可以直接在视图上复制常量;如果是简单的列引用,校验它是否可以从视图中获取;对于表达式,如果表达式的列可以从物化视图中获取,就直接获取,否则校验不通过。 +物化视图的底层实现依托于Duplicate模型的OLAP表,这一设计使其理论上能够支持Duplicate模型的所有核心功能。然而, +为了保障物化视图能够稳定且高效地执行数据刷新任务,我们对其功能进行了一系列必要的限制。以下是具体的限制内容: -**4. 输出数据重复度一致校验** +- 物化视图的分区是基于其基表自动创建和维护的,因此用户不能对物化视图进行分区操作 +- 由于物化视图背后有相关的作业(JOB)需要处理,所以不能使用删除表(DELETE TABLE)或重命名表(RENAME TABLE)的命令来操作物化视图。 + 相反,需要使用物化视图自身的命令来进行这些操作。 +- 物化视图的列数据类型是根据创建时指定的查询语句自动推导得出的,因此这些数据类型不能被修改。否则,可能会导致物化视图的刷新任务失败。 +- 物化视图具有一些 Duplicate 表没有的属性(property),这些属性需要通过物化视图的命令进行修改。 +而其他公用的属性则需要使用 ALTER TABLE 命令进行修改。 -对于查询和使用物化视图后获取的数据,对于重复的行,需要有相同的重复行数。如果查询和物化视图引用的表相同,就不会出现上述问题。只有当查询和物化视图引用的表不同时,才有可能出现重复的行且重复行数不同的情况,比如星型查询多一个连接关系时,如果连接键不是主外键的关系,就容易造成数据膨胀,导致数据重复因数不一致。 -通常需要校验物化视图和查询在相同表情况下的 JOIN 类型,以及在不同表情况下是否满足 JOIN 消除。 +## 更多参考 +创建、查询与维护异步物化视图,可以参考 [创建、查询与维护异步物化视图](../functions-and-demands) -**5. 聚合校验** +最佳实践,可以参考 [最佳实践](../use-guide) -- 物化的维度是否比查询更细,是否包含查询的维度 +常见问题,可以参考 [常见问题](../faq) -- 查询使用的聚合函数是否可以从物化视图获取,或者是否可以通过物化视图的函数上卷获得。 \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/use-guide.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/use-guide.md index 03822786091..2603915594a 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/use-guide.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/async-materialized-view/use-guide.md @@ -1,6 +1,6 @@ --- { - "title": "异步物化视图使用与实践", + "title": "最佳实践", "language": "zh-CN" } --- @@ -25,24 +25,24 @@ under the License. --> ## 异步物化视图使用原则 +- **时效性考虑:** 异步物化视图通常用于对数据时效性要求不高的场景,一般是 T+1 的数据。如果时效性要求高,应考虑使用同步物化视图。 -1. **时效性考虑:** 异步物化视图通常用于对数据时效性要求不高的场景,一般是 T+1 的数据。如果时效性要求高,应考虑使用同步物化视图。 +- **加速效果与一致性考虑:** 在查询加速场景,创建物化视图时,DBA 应将常见查询 SQL 模式分组,尽量使组之间无重合。SQL 模式组划分越清晰,物化视图构建的质量越高。一个查询可能使用多个物化视图,同时一个物化视图也可能被多个查询使用。构建物化视图需要综合考虑命中物化视图的响应时间(加速效果)、构建成本、数据一致性要求等。 -2. **加速效果与一致性考虑:** 在查询加速场景,创建物化视图时,DBA 应将常见查询 SQL 模式分组,尽量使组之间无重合。SQL 模式组划分越清晰,物化视图构建的质量越高。一个查询可能使用多个物化视图,同时一个物化视图也可能被多个查询使用。构建物化视图需要综合考虑命中物化视图的响应时间(加速效果)、构建成本、数据一致性要求等。 - -3. **物化视图定义与构建成本考虑:** +- **物化视图定义与构建成本考虑:** - 物化视图定义和原查询越接近,查询加速效果越好,但物化的通用性和复用性越差,意味着构建成本越高。 - 物化视图定义越通用(例如没有 WHERE 条件和更多聚合维度),查询加速效果较低,但物化的通用性和复用性越好,意味着构建成本越低。 -需要注意: +:::caution 注意 +- **物化视图数量控制:** 物化视图并非越多越好。物化视图构建和刷新需要资源。物化视图参与透明改写, CBO 代价模型选择最优物化视图需要时间。理论上,物化视图越多,透明改写的时间越长。 -1. **物化视图数量控制:** 物化视图并非越多越好。物化视图参与透明改写,且 CBO 代价模型选择需要时间。理论上,物化视图越多,透明改写的时间越长,且物化视图构建和刷新占用的资源越大。 +- **定期检查物化视图使用状态:** 如果未使用,应及时删除。 -2. **定期检查物化视图使用状态:** 如果未使用,应及时删除。 +- **基表数据更新频率:** 如果物化视图的基表数据频繁更新,可能不太适合使用物化视图,因为这会导致物化视图频繁失效,不能用于透明改写(可直查)。如果需要使用此类物化视图进行透明改写,需要允许查询的数据有一定的时效延迟,并可以设定`grace_period`。具体见`grace_period`的适用介绍。 +::: -3. **基表数据更新频率:** 如果物化视图的基表数据频繁更新,可能不太适合使用物化视图,因为这会导致物化视图频繁失效,不能用于透明改写(可直查)。如果需要使用此类物化视图进行透明改写,需要允许查询的数据有一定的时效延迟,并可以设定`grace_period`。具体见`grace_period`的适用介绍。 ## 物化视图刷新方式选择原则 @@ -54,9 +54,11 @@ under the License. - 物化视图的定义 SQL 和分区字段满足分区推导的要求,即符合分区增量更新的要求。详细要求可参考:[CREATE-ASYNC-MATERIALIZED-VIEW](../../../sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-ASYNC-MATERIALIZED-VIEW/#refreshmethod) -- 物化视图分区数不多。 +- 物化视图分区数不多,分区过多会导致分区多物化视图构建时间会过长。 -当物化视图的部分分区失效时,透明改写可以使用物化视图的有效分区 UNION ALL 基表返回数据。如果不能构建分区物化视图,可以考虑选择全量刷新的物化视图。 +当物化视图的部分分区失效时,透明改写可以使用物化视图的有效分区 UNION ALL 基表返回数据。 + +如果不能构建分区物化视图,可以考虑选择全量刷新的物化视图。 ## 分区物化视图常见使用方式 @@ -68,17 +70,17 @@ under the License. 确认物化视图分区状态的命令详见查看物化视图状态,主要是`show partitions from mv_name`命令。 -- 如果物化视图引用的非分区表发生数据变更,会触发物化视图所有分区失效,导致此物化视图不能用于透明改写。需要刷新物化视图所有分区的数据,命令为`REFRESH MATERIALIZED VIEW mv1 AUTO;`。此命令会尝试刷新物化视图,如果满足分区增量构建的条件则进行分区增量构建,否则退化为全量构建。 +- 如果物化视图引用的非分区表发生数据变更,会触发物化视图所有分区失效,导致此物化视图不能用于透明改写。需要刷新物化视图所有分区的数据,命令为`REFRESH MATERIALIZED VIEW mv1 AUTO;`。此命令会尝试刷新物化视图所有数据变化的分区。 因此,一般将数据频繁变化的表放在分区物化视图引用的分区表,将不经常变化的维表放在非引用分区表的位置。 分区物化视图的透明改写是分区粒度的,即使物化视图的部分分区失效,此物化视图仍然可用于透明改写。但如果只查询了一个分区,并且物化视图这个分区数据失效了,那么此物化视图不能用于透明改写。 -举例 1: +例如: ```sql - CREATE TABLE IF NOT EXISTS lineitem ( +CREATE TABLE IF NOT EXISTS lineitem ( l_orderkey INTEGER NOT NULL, l_partkey INTEGER NOT NULL, l_suppkey INTEGER NOT NULL, @@ -102,36 +104,40 @@ under the License. ) PARTITION BY RANGE(l_ordertime) ( FROM ('2024-05-01') TO ('2024-06-30') INTERVAL 1 DAY - ) DISTRIBUTED BY HASH(l_orderkey) BUCKETS 3 PROPERTIES ("replication_num" = "1"); - - insert into lineitem values (1, 2, 3, 4, '2024-05-01 01:45:05', 5.5, 6.5, 0.1, 8.5, 'o', 'k', '2024-05-01', '2024-05-01', '2024-05-01', 'a', 'b', 'yyyyyyyyy'), - (1, 2, 3, 4, '2024-05-15 02:35:05', 5.5, 6.5, 0.15, 8.5, 'o', 'k', '2024-05-15', '2024-05-15', '2024-05-15', 'a', 'b', 'yyyyyyyyy'), - (2, 2, 3, 5, '2024-05-25 08:30:06', 5.5, 6.5, 0.2, 8.5, 'o', 'k', '2024-05-25', '2024-05-25', '2024-05-25', 'a', 'b', 'yyyyyyyyy'), - (3, 4, 3, 6, '2024-06-02 09:25:07', 5.5, 6.5, 0.3, 8.5, 'o', 'k', '2024-06-02', '2024-06-02', '2024-06-02', 'a', 'b', 'yyyyyyyyy'), - (4, 4, 3, 7, '2024-06-15 13:20:09', 5.5, 6.5, 0, 8.5, 'o', 'k', '2024-06-15', '2024-06-15', '2024-06-15', 'a', 'b', 'yyyyyyyyy'), - (5, 5, 6, 8, '2024-06-25 15:15:36', 5.5, 6.5, 0.12, 8.5, 'o', 'k', '2024-06-25', '2024-06-25', '2024-06-25', 'a', 'b', 'yyyyyyyyy'), - (5, 5, 6, 9, '2024-06-29 21:10:52', 5.5, 6.5, 0.1, 8.5, 'o', 'k', '2024-06-30', '2024-06-30', '2024-06-30', 'a', 'b', 'yyyyyyyyy'), - (5, 6, 5, 10, '2024-06-03 22:05:50', 7.5, 8.5, 0.1, 10.5, 'k', 'o', '2024-06-03', '2024-06-03', '2024-06-03', 'c', 'd', 'xxxxxxxxx'); + ) +DISTRIBUTED BY HASH(l_orderkey) BUCKETS 3; + +INSERT INTO lineitem VALUES +(1, 2, 3, 4, '2024-05-01 01:45:05', 5.5, 6.5, 0.1, 8.5, 'o', 'k', '2024-05-01', '2024-05-01', '2024-05-01', 'a', 'b', 'yyyyyyyyy'), +(1, 2, 3, 4, '2024-05-15 02:35:05', 5.5, 6.5, 0.15, 8.5, 'o', 'k', '2024-05-15', '2024-05-15', '2024-05-15', 'a', 'b', 'yyyyyyyyy'), +(2, 2, 3, 5, '2024-05-25 08:30:06', 5.5, 6.5, 0.2, 8.5, 'o', 'k', '2024-05-25', '2024-05-25', '2024-05-25', 'a', 'b', 'yyyyyyyyy'), +(3, 4, 3, 6, '2024-06-02 09:25:07', 5.5, 6.5, 0.3, 8.5, 'o', 'k', '2024-06-02', '2024-06-02', '2024-06-02', 'a', 'b', 'yyyyyyyyy'), +(4, 4, 3, 7, '2024-06-15 13:20:09', 5.5, 6.5, 0, 8.5, 'o', 'k', '2024-06-15', '2024-06-15', '2024-06-15', 'a', 'b', 'yyyyyyyyy'), +(5, 5, 6, 8, '2024-06-25 15:15:36', 5.5, 6.5, 0.12, 8.5, 'o', 'k', '2024-06-25', '2024-06-25', '2024-06-25', 'a', 'b', 'yyyyyyyyy'), +(5, 5, 6, 9, '2024-06-29 21:10:52', 5.5, 6.5, 0.1, 8.5, 'o', 'k', '2024-06-30', '2024-06-30', '2024-06-30', 'a', 'b', 'yyyyyyyyy'), +(5, 6, 5, 10, '2024-06-03 22:05:50', 7.5, 8.5, 0.1, 10.5, 'k', 'o', '2024-06-03', '2024-06-03', '2024-06-03', 'c', 'd', 'xxxxxxxxx'); - CREATE TABLE IF NOT EXISTS partsupp ( +CREATE TABLE IF NOT EXISTS partsupp ( ps_partkey INTEGER NOT NULL, ps_suppkey INTEGER NOT NULL, ps_availqty INTEGER NOT NULL, ps_supplycost DECIMALV3(15, 2) NOT NULL, ps_comment VARCHAR(199) NOT NULL - ) DUPLICATE KEY(ps_partkey, ps_suppkey) DISTRIBUTED BY HASH(ps_partkey) BUCKETS 3 PROPERTIES ("replication_num" = "1"); - - - insert into partsupp values - (2, 3, 9, 10.01, 'supply1'), - (4, 3, 9, 10.01, 'supply2'), - (5, 6, 9, 10.01, 'supply3'), - (6, 5, 10, 11.01, 'supply4'); + ) +DUPLICATE KEY(ps_partkey, ps_suppkey) +DISTRIBUTED BY HASH(ps_partkey) BUCKETS 3; + + +INSERT INTO partsupp VALUES +(2, 3, 9, 10.01, 'supply1'), +(4, 3, 9, 10.01, 'supply2'), +(5, 6, 9, 10.01, 'supply3'), +(6, 5, 10, 11.01, 'supply4'); ``` 在这个例子中,`orders`表的`o_ordertime`字段是分区字段,类型是`DATETIME`,按照天分区。 -查询主要是按照“天”的粒度,查询粒度比较粗: +查询主要是按照"天"的粒度 ```sql SELECT @@ -152,16 +158,15 @@ GROUP BY ps_partkey; ``` -为了不让物化视图每次刷新的分区数量过多,物化视图的分区粒度可以和基表`orders`一致,按“天”分区。 +为了不让物化视图每次刷新的分区数量过多,物化视图的分区粒度可以和基表`orders`一致,也按"天"分区。 -物化视图的定义 SQL 的粒度可以按照“天”,并且按照“天”来聚合数据, +物化视图的定义 SQL 的粒度可以按照"天",并且按照"天"来聚合数据, ```sql CREATE MATERIALIZED VIEW rollup_partition_mv BUILD IMMEDIATE REFRESH AUTO ON MANUAL partition by(order_date) DISTRIBUTED BY RANDOM BUCKETS 2 -PROPERTIES ('replication_num' = '1') AS SELECT l_linestatus, @@ -180,130 +185,6 @@ GROUP BY date_trunc(l_ordertime, 'day'); ``` -## 查看物化视图状态 - -通常物化视图会出现两种状态: - -- **状态正常:** 指的是当前物化视图是否可用于透明改写。 - -- **不可用、状态不正常:** 的是物化视图不能用于透明改写的简称。尽管如此,该物化视图还是可以直查的。 - -### 查看物化视图元数据 - -```sql -select * from mv_infos('database'='db_name') -where Name = 'mv_name' \G -``` - -返回结果如下: - -```sql -*************************** 1. row *************************** - Id: 139570 - Name: mv11 - JobName: inner_mtmv_139570 - State: NORMAL -SchemaChangeDetail: - RefreshState: SUCCESS - RefreshInfo: BUILD IMMEDIATE REFRESH AUTO ON MANUAL - QuerySql: SELECT l_shipdate, l_orderkey, O_ORDERDATE, count(*) -FROM lineitem -LEFT OUTER JOIN orders on l_orderkey = o_orderkey -GROUP BY l_shipdate, l_orderkey, O_ORDERDATE - EnvInfo: EnvInfo{ctlId='0', dbId='16813'} - MvProperties: {} - MvPartitionInfo: MTMVPartitionInfo{partitionType=FOLLOW_BASE_TABLE, relatedTable=lineitem, relatedCol='l_shipdate', partitionCol='l_shipdate'} -SyncWithBaseTables: 1 -``` - -- **SyncWithBaseTables:** 表示物化视图和基表的数据是否一致。 - - - 对于全量构建的物化视图,此字段为 1,表明此物化视图可用于透明改写。 - - - 对于分区增量的物化视图,分区物化视图是否可用,是以分区粒度去看的。也就是说,即使物化视图的部分分区不可用,但只要查询的是有效分区,那么此物化视图依旧可用于透明改写。是否能透明改写,主要看查询所用分区的 `SyncWithBaseTables` 字段是否一致。如果 `SyncWithBaseTables` 是 1,此分区可用于透明改写;如果是 0,则不能用于透明改写。 - -- **JobName:** 物化视图构建 Job 的名称,每个物化视图有一个 Job,每次刷新会有一个新的 Task,Job 和 Task 是 1:n 的关系 - -- **State:** 如果变为 SCHEMA_CHANGE,代表基表的 Schema 发生了变化,此时物化视图将不能用来透明改写 (但是不影响直接查询物化视图),下次刷新任务如果执行成功,将恢复为 NORMAL。 - -- **SchemaChangeDetail:** 表示 SCHEMA_CHANGE 发生的原因。 - -- **RefreshState:** 物化视图最后一次任务刷新的状态。如果为 FAIL,代表执行失败,可以通过 `tasks() `命令进一步定位失败原因。Task 命令见本文[查看物化视图 Task 状态](#查看物化视图-task-状态)。 - -- **SyncWithBaseTables:** 是否和基表数据同步。1 为同步,0 为不同步。如果不同步,可通过 `show partitions` 进一步判断哪个分区不同步。`show partitions` 见下文分区物化视图查看 SyncWithBaseTables 状态方法。 - -**分区物化视图查看 SyncWithBaseTables 状态方法** - -运行 `show partitions from mv_name`查看查询使用的分区是否有效,返回结果如下: - -```Plain -show partitions from mv11; -+-------------+---------------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+ -| PartitionId | PartitionName | VisibleVersion | VisibleVersionTime | State | PartitionKey | Range | DistributionKey | Buckets | ReplicationNum | StorageMedium | CooldownTime | RemoteStoragePolicy | LastConsistencyCheckTime | DataSize | IsInMemory | ReplicaAllocation | IsMutable | SyncWithBaseTables | UnsyncTables | -+-------------+---------------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+ -| 140189 | p_20231016_20231017 | 1 | 2024-06-21 10:31:45 | NORMAL | l_shipdate | [types: [DATEV2]; keys: [2023-10-16]; ..types: [DATEV2]; keys: [2023-10-17]; ) | l_orderkey | 10 | 1 | HDD | 9999-12-31 23:59:59 | | NULL | 0.000 | false | tag.location.default: 1 | true | true | [] | -| 139995 | p_20231018_20231019 | 2 | 2024-06-21 10:31:44 | NORMAL | l_shipdate | [types: [DATEV2]; keys: [2023-10-18]; ..types: [DATEV2]; keys: [2023-10-19]; ) | l_orderkey | 10 | 1 | HDD | 9999-12-31 23:59:59 | | NULL | 880.000 B | false | tag.location.default: 1 | true | true | [] | -| 139898 | p_20231019_20231020 | 2 | 2024-06-21 10:31:43 | NORMAL | l_shipdate | [types: [DATEV2]; keys: [2023-10-19]; ..types: [DATEV2]; keys: [2023-10-20]; ) | l_orderkey | 10 | 1 | HDD | 9999-12-31 23:59:59 | | NULL | 878.000 B | false | tag.location.default: 1 | true | true | [] | -+-------------+---------------------+----------------+---------------------+--------+--------------+--------------------------------------------------------------------------------+-----------------+---------+----------------+---------------+---------------------+---------------------+--------------------------+-----------+------------+-------------------------+-----------+--------------------+--------------+ -``` - -主要查看 `SyncWithBaseTables` 字段是否为 true。false 表示此分区不可用于透明改写。 - -### 查看物化视图 Task 状态 - -每个物化视图有一个 Job,每次刷新会有一个新的 Task,Job 和 Task 是 1:n 的关系。 - -根据 `JobName` 查看物化视图的 Task 状态,运行如下语句,可以查看刷新任务的状态和进度: - -```sql -select * from tasks("type"="mv") -where mvName = 'mv_name' -order by CreateTime desc \G -``` - -返回结果如下: - -```sql -*************************** 1. row *************************** - TaskId: 167019363907545 - JobId: 139872 - JobName: inner_mtmv_139570 - MvId: 139570 - MvName: mv11 - MvDatabaseId: 16813 - MvDatabaseName: regression_test_nereids_rules_p0_mv - Status: SUCCESS - ErrorMsg: - CreateTime: 2024-06-21 10:31:43 - StartTime: 2024-06-21 10:31:43 - FinishTime: 2024-06-21 10:31:45 - DurationMs: 2466 - TaskContext: {"triggerMode":"SYSTEM","isComplete":false} - RefreshMode: COMPLETE -NeedRefreshPartitions: ["p_20231023_20231024","p_20231019_20231020","p_20231020_20231021","p_20231027_20231028","p_20231030_20231031","p_20231018_20231019","p_20231024_20231025","p_20231021_20231022","p_20231029_20231030","p_20231028_20231029","p_20231025_20231026","p_20231022_20231023","p_20231031_20231101","p_20231016_20231017","p_20231026_20231027"] - CompletedPartitions: ["p_20231023_20231024","p_20231019_20231020","p_20231020_20231021","p_20231027_20231028","p_20231030_20231031","p_20231018_20231019","p_20231024_20231025","p_20231021_20231022","p_20231029_20231030","p_20231028_20231029","p_20231025_20231026","p_20231022_20231023","p_20231031_20231101","p_20231016_20231017","p_20231026_20231027"] - Progress: 100.00% (15/15) - LastQueryId: fe700ca3d6504521-bb522fc9ccf615e3 -``` - -- NeedRefreshPartitions,CompletedPartitions 记录的是此次 Task 刷新的分区。 - -- Status:如果为 FAILED,代表运行失败,可通过 ErrorMsg 查看失败原因,也可通过 LastQueryId 来搜索 Doris 的日志,获取更详细的错误信息。目前任务失败会导致已有物化视图不可用,后面会改成尽管任务失败,但是已存在的物化视图可用于透明改写。 - -- ErrorMsg:失败原因。 - -- RefreshMode:complete 代表刷新了全部分区,PARTIAL 代表刷新了部分分区,NOT_REFRESH 代表不需要刷新任何分区。 - -:::info 备注 -- 如果物化视图创建的时候设置了 `grace_period` 属性,那么即使 `SyncWithBaseTables` 是 false 或者 0,有些情况下它依然可用于透明改写。 - -- `grace_period` 的单位是秒,指的是容许物化视图和所用基表数据不一致的时间。 - - - 如果设置成 0,意味着要求物化视图和基表数据保持一致,此物化视图才可用于透明改写。 - - - 如果设置成 10,意味着物化视图和基表数据允许 10 秒的延迟,如果物化视图的数据和基表的数据有延迟,在 10 秒内,此物化视图都可以用于透明改写。 -::: - ## 如何使用物化视图加速查询 使用物化视图查询加速,首先需要查看 profile 文件,找到一个查询消耗时间最多的操作,一般出现在连接(Join)、聚合(Aggregate)、过滤(Filter)或者表达式计算(Calculated Expressions)。 @@ -382,7 +263,9 @@ GROUP BY l_suppkey; ``` -根据以上两个 SQL 查询,我们可以构建一个更为通用的包含 Aggregate 的物化视图。在这个物化视图中,我们将 l_partkey 和 l_suppkey 都作为聚合的 group by 维度,并将 o_orderdate 作为过滤条件。值得注意的是,o_orderdate 不仅在物化视图的条件补偿中使用,同时也需要被包含在物化视图的聚合 group by 维 度中。 +根据以上两个 SQL 查询,我们可以构建一个更为通用的包含 Aggregate 的物化视图。在这个物化视图中,我们将 l_partkey 和 l_suppkey 都作为聚合的 group by +维度,并将 o_orderdate 作为过滤条件。值得注意的是,o_orderdate 不仅在物化视图的条件补偿中使用, +同时也需要被包含在物化视图的聚合 group by 维度中。 通过这种方式构建的物化视图后,查询 1 和查询 2 都可以命中该物化视图,物化视图定义如下: @@ -390,7 +273,6 @@ GROUP BY CREATE MATERIALIZED VIEW common_agg_mv BUILD IMMEDIATE REFRESH AUTO ON MANUAL DISTRIBUTED BY RANDOM BUCKETS 2 -PROPERTIES ('replication_num' = '1') AS SELECT l_linestatus, @@ -414,8 +296,9 @@ GROUP BY ## 使用场景 -### 场景一:多表连接聚合查询加速 +### 场景一:查询加速 +#### 用例1 多表连接聚合查询加速 通过构建更通用的物化视图能够加速多表连接聚合查询。 以下面三个查询 SQL 为例: @@ -478,7 +361,6 @@ FROM CREATE MATERIALIZED VIEW common_join_mv BUILD IMMEDIATE REFRESH AUTO ON MANUAL DISTRIBUTED BY RANDOM BUCKETS 2 -PROPERTIES ('replication_num' = '1') AS SELECT l_linestatus, @@ -496,7 +378,6 @@ FROM CREATE MATERIALIZED VIEW target_agg_mv BUILD IMMEDIATE REFRESH AUTO ON MANUAL DISTRIBUTED BY RANDOM BUCKETS 2 -PROPERTIES ('replication_num' = '1') AS SELECT l_linestatus, @@ -514,7 +395,7 @@ GROUP BY o_shippriority; ``` -### 场景二:日志查询加速 +#### 用例2 日志查询加速 在日志查询加速场景中,建议不局限于单独使用异步物化视图,可以结合同步物化视图。 @@ -538,7 +419,7 @@ PARTITION BY RANGE(time) FROM ("2024-07-01 00:00:00") TO ("2024-07-15 00:00:00") INTERVAL 1 HOUR ) DISTRIBUTED BY HASH(event_id) -BUCKETS 3 PROPERTIES ("replication_num" = "1"); +BUCKETS 3; ``` 物化视图可以按照分钟聚合数据,这样也能达到一定的聚合效果。例如: @@ -604,6 +485,96 @@ SELECT cast(FLOOR(MINUTE(`time`) / 15) as decimal(9, 0)); ``` +### 场景二:数据建模(ETL) + +有时用户会使用事实表和维度表加工成一张汇总表,之后对此汇总表进行 Ad-hoc 查询。此汇总表也可作为基础指标表,用于后续的建模。 + +此时,可以利用物化视图对基表的数据进行建模。之后,还可以利用创建好的物化视图创建更高层级的物化视图(2.1.3 支持),灵活满足不同的需求。 + +不同层级的物化视图都可以自己设置刷新方式,例如: + +- 第一层的物化视图可以设置为定时刷新,第二层的设置为触发刷新。这样,第一层的物化视图刷新完成后,会自动触发第二层物化视图的刷新。 + +- 如果每层的物化视图都设置为定时刷新,那么第二层物化视图刷新的时候,不会考虑第一层的物化视图数据是否和基表同步,只会把第一层物化视图的数据加工后同步到第二层。 + +原始查询(未使用物化视图): +```sql +SELECT +n_name, +date_trunc(o.o_orderdate, 'month') as month, +count(distinct o.o_orderkey) as order_count, +sum(l.l_extendedprice * (1 - l.l_discount)) as revenue +FROM orders o +JOIN lineitem l ON o.o_orderkey = l.l_orderkey +JOIN customer c ON o.o_custkey = c.c_custkey +JOIN nation n ON c.c_nationkey = n.n_nationkey +JOIN region r ON n.n_regionkey = r.r_regionkey +GROUP BY n_name, month; +``` + +使用异步物化视图分层建模: + +构建 DWD 层(明细数据),处理订单明细宽表 +```sql +CREATE MATERIALIZED VIEW dwd_order_detail +BUILD IMMEDIATE REFRESH AUTO ON COMMIT +DISTRIBUTED BY RANDOM BUCKETS 16 +AS +select +o.o_orderkey, +o.o_custkey, +o.o_orderstatus, +o.o_totalprice, +o.o_orderdate, +c.c_name, +c.c_nationkey, +n.n_name as nation_name, +r.r_name as region_name, +l.l_partkey, +l.l_quantity, +l.l_extendedprice, +l.l_discount, +l.l_tax +from orders o +join customer c on o.o_custkey = c.c_custkey +join nation n on c.c_nationkey = n.n_nationkey +join region r on n.n_regionkey = r.r_regionkey +join lineitem l on o.o_orderkey = l.l_orderkey; +``` + +构建 DWS 层(汇总数据),进行每日订单汇总 +```sql +CREATE MATERIALIZED VIEW dws_daily_sales +BUILD IMMEDIATE REFRESH AUTO ON COMMIT +DISTRIBUTED BY RANDOM BUCKETS 16 +AS +select +date_trunc(o_orderdate, 'month') as month, +nation_name, +region_name, +bitmap_union(to_bitmap(o_orderkey)) as order_count, +sum(l_extendedprice * (1 - l_discount)) as net_revenue +from dwd_order_detail +group by +date_trunc(o_orderdate, 'month'), +nation_name, +region_name; +``` + + +使用物化视图优化查询如下: +```sql +SELECT +nation_name, +month, +bitmap_union_count(order_count), +sum(net_revenue) as revenue +FROM dws_daily_sales +GROUP BY nation_name, month; +``` + + + ### 场景三:湖仓一体联邦数据查询 很多用户有基于 Doris 进行联邦数据查询的需求,Doris 的多源数据目录(Multi-Catalog)功能使得这一需求变得十分便捷。用户只需创建一个 Catalog,无需将数据迁移到 Doris,即可通过 Doris 对外部数据进行查询。 @@ -612,18 +583,175 @@ SELECT 为了解决这个问题,可以基于外部 Catalog 创建异步物化视图。由于物化视图本身的数据是存储在 Doris 内部的,所以查询物化视图的速度会很快。因此,对于响应速度要求比较高的场景,我们可以考虑基于外部 Catalog 创建一个物化视图。 + +如下,以 Hive 示例说明: + +基于 Hive 创建 Catalog,使用 TPC-H 数据集 +```sql +CREATE CATALOG hive_catalog PROPERTIES ( +'type'='hms', -- hive meta store 地址 +'hive.metastore.uris' = 'thrift://172.21.0.1:7004' +); +``` + +基于 Hive Catalog 创建物化视图 +```sql +-- 物化视图只能在 internal 的 catalog 上创建, 切换到内部 catalog +switch internal; +create database hive_mv_db; +use hive_mv_db; + +CREATE MATERIALIZED VIEW external_hive_mv +BUILD IMMEDIATE REFRESH AUTO ON MANUAL +DISTRIBUTED BY RANDOM BUCKETS 12 +AS +SELECT +n_name, +o_orderdate, +sum(l_extendedprice * (1 - l_discount)) AS revenue +FROM +customer, +orders, +lineitem, +supplier, +nation, +region +WHERE +c_custkey = o_custkey +AND l_orderkey = o_orderkey +AND l_suppkey = s_suppkey +AND c_nationkey = s_nationkey +AND s_nationkey = n_nationkey +AND n_regionkey = r_regionkey +AND r_name = 'ASIA' +GROUP BY +n_name, +o_orderdate; +``` + +运行如下的查询,通过透明改写自动使用物化视图加速查询。 +```sql +SELECT +n_name, +sum(l_extendedprice * (1 - l_discount)) AS revenue +FROM +customer, +orders, +lineitem, +supplier, +nation, +region +WHERE +c_custkey = o_custkey +AND l_orderkey = o_orderkey +AND l_suppkey = s_suppkey +AND c_nationkey = s_nationkey +AND s_nationkey = n_nationkey +AND n_regionkey = r_regionkey +AND r_name = 'ASIA' +AND o_orderdate >= DATE '1994-01-01' +AND o_orderdate < DATE '1994-01-01' + INTERVAL '1' YEAR +GROUP BY +n_name +ORDER BY +revenue DESC; +``` + :::tip 提示 -在湖仓一体场景下,使用外表透明改写之前需要打开 `materialized_view_rewrite_enable_contain_external_table` 开关,详情可参考[异步物化视图功能描述](../async-materialized-view/functions-and-demands)。 +Doris 暂无法感知除 Hive 外的其他外表数据变更。当外表数据不一致时,使用物化视图可能出现数据不一致的情况。以下开关表示:参与透明改写的物化视图是否允许包含外表,默认false。如接受数据不一致或者通过定时刷新来保证外表数据一致性,可以将此开关设置成true。 +设置包含外表的物化视图是否可用于透明改写,默认不允许,如果可以接受数据不一致或者可以自行保证数据一致, 可以开启 + +`SET materialized_view_rewrite_enable_contain_external_table = true;` + +如果物化视图在 MaterializedViewRewriteSuccessButNotChose 状态,说明改写成功但 plan 未被 CBO 选择,可能是因为外表的统计信息不完整。 +启用统计信息从文件中获取行数 + +``SET enable_get_row_count_from_file_list = true;`` + +查看外表统计信息,确认是否已收集完整 + +``SHOW TABLE STATS external_table_name;`` + ::: -### 场景四:数据建模(ETL) -有时用户会使用事实表和维度表加工成一张汇总表,之后对此汇总表进行 Ad-hoc 查询。此汇总表也可作为基础指标表,用于后续的建模。 +### 场景四:提升写入效率,减少资源竞争 +在高吞吐的数据写入的场景中,系统性能的稳定性与数据处理的高效性同样重要。通过异步物化视图灵活的刷新策略,用户可以根据具体场景选择合适的刷新方式, +从而降低写入压力,避免资源争抢。 -此时,可以利用物化视图对基表的数据进行建模。之后,还可以利用创建好的物化视图创建更高层级的物化视图(2.1.3 支持),灵活满足不同的需求。 +相比之下,异步物化视图提供了手动触发、触发式、周期性触发三种灵活的刷新策略。用户可以根据场景需求差异,选择合适的刷新策略。当基表数据变更时,不会立即触发物化视图刷新,延迟刷新有利于降低资源压力,有效避免写入资源争抢。 -不同层级的物化视图都可以自己设置刷新方式,例如: +如下所示,选择的刷新方式为定时刷新,每 2 小时刷新一次。当orders 和 lineitem 导入数据时,不会立即触发物化视图刷新。 -- 第一层的物化视图可以设置为定时刷新,第二层的设置为触发刷新。这样,第一层的物化视图刷新完成后,会自动触发第二层物化视图的刷新。 +```sql +CREATE MATERIALIZED VIEW common_schedule_join_mv +BUILD IMMEDIATE REFRESH AUTO ON SCHEDULE EVERY 2 HOUR +DISTRIBUTED BY RANDOM BUCKETS 16 +AS +SELECT +l_linestatus, +l_extendedprice * (1 - l_discount), +o_orderdate, +o_shippriority +FROM +orders +LEFT JOIN lineitem ON l_orderkey = o_orderkey; +``` + +透明改写能够对查询 SQL 的改写,实现了查询加速,同时也能对导入 SQL 进行改写,从而提升导入效率。 +从 2.1.6 版本开始,当物化视图和基表数据强一致时,可对 DML 操作如 Insert Into 或者 Insert Overwrite 进行透明改写,这对于数据导入场景的性能提升有显著效果。 + +1. 创建 Insert Into 数据的目标表 +```sql +CREATE TABLE IF NOT EXISTS target_table ( +orderdate DATE NOT NULL, +shippriority INTEGER NOT NULL, +linestatus CHAR(1) NOT NULL, +sale DECIMALV3(15,2) NOT NULL +) +DUPLICATE KEY(orderdate, shippriority) +DISTRIBUTED BY HASH(shippriority) BUCKETS 3; +``` + +2. common_schedule_join_mv +```sql +CREATE MATERIALIZED VIEW common_schedule_join_mv +BUILD IMMEDIATE REFRESH AUTO ON SCHEDULE EVERY 2 HOUR +DISTRIBUTED BY RANDOM BUCKETS 16 +AS +SELECT +l_linestatus, +l_extendedprice * (1 - l_discount), +o_orderdate, +o_shippriority +FROM +orders +LEFT JOIN lineitem ON l_orderkey = o_orderkey; +``` + +未经改写的导入语句如下: +```sql +INSERT INTO target_table +SELECT +o_orderdate, +o_shippriority, +l_linestatus, +l_extendedprice * (1 - l_discount) +FROM +orders +LEFT JOIN lineitem ON l_orderkey = o_orderkey; +``` + +经过透明改写后,语句如下: + +```sql +INSERT INTO target_table +SELECT * +FROM common_schedule_join_mv; +``` + +需要注意的是:如果 DML 操作的是无法感知数据变更的外表,透明改写可能导致基表最新数据无法实时导入目标表。如果用户可以接受数据不一致或能够自行保证数据一致性,可以打开如下开关 + +DML 时,当物化视图存在无法实时感知数据的外表时,是否开启基于结构信息的物化视图透明改写,默认关闭 -- 如果每层的物化视图都设置为定时刷新,那么第二层物化视图刷新的时候,不会考虑第一层的物化视图数据是否和基表同步,只会把第一层物化视图的数据加工后同步到第二层。 \ No newline at end of file +`SET enable_dml_materialized_view_rewrite_when_base_table_unawareness = true;` \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-ASYNC-MATERIALIZED-VIEW.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-ASYNC-MATERIALIZED-VIEW.md index b786d141065..55cd1ab30a2 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-ASYNC-MATERIALIZED-VIEW.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-ASYNC-MATERIALIZED-VIEW.md @@ -224,6 +224,11 @@ partition by (date_trunc(`k2`,'month')) `enable_nondeterministic_function`:物化视图定义 SQL 是否允许包含 nondeterministic 函数,比如 current_date(), now(), random()等,如果 是 true, 允许包含,否则不允许包含, 默认不允许包含。 +:::tips +自 2.1.7 版本起支持 use_for_rewrite +::: +`use_for_rewrite`:标识此物化视图是否参与到透明改写中,如果为 false,不参与到透明改写,默认是 true。数据建模场景中,如果物化视图只是用于直查,物化视图可以设置此属性,从而不参与透明改写,提高查询响应速度。 + `query`:创建物化视图的查询语句,其结果即为物化视图中的数据 --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org