CREATE MATERIALIZED VIEW

更新时间:2025-03-13 06:01:14

本文介绍CREATE MATERIALIZED VIEW的语法。通过本文,您可以了解如何创建全量刷新或增量刷新的物化视图,如何定义物化视图的刷新时间。

语法

CREATE [OR REPLACE] MATERIALIZED VIEW mv_name
[mv_definition]
[mv_properties]
[REFRESH [COMPLETE|FAST]]
[ON [DEMAND |OVERWRITE]]
[START WITH date] [NEXT date]
[[DISABLE|ENABLE] QUERY REWRITE]
AS 
query_body

参数说明

OR REPLACE

可选参数

创建后是否可变更:不可变更

3.1.4.7及以上内核版本集群支持该参数。
  • 若不存在重名的物化视图,则直接创建一个新视图。

  • 若存在重名的物化视图,则先删除原有的重名物化视图,再重新创建。

mv_definition

可选参数

创建后是否可变更:不可变更

定义物化视图的结构。

您可以不显式定义物化视图的结构。未显式定义物化视图的结构时,系统会将query_body输出的列作为物化视图的列,为物化视图定义主键,为所有列建立索引,存储策略为热存储,引擎为XUANWU。

如果您需要手动定义物化视图的结构(包括分布键、分区键、主键、索引和冷热数据存储策略等),方法与CREATE TABLE定义表结构的方法相同。例如,如果不需要全列建立索引,您可以指定INDEX关键字对特定列建立索引。又例如,如果希望节省物化视图的存储成本,您可以定义物化视图的存储策略为冷热混存,甚至只保留最近一年的数据

主键规则
  • 全量刷新:若未显式定义主键,系统将自动生成列__adb_auto_id__作为物化视图的主键。若需要显式定义主键,您可以将query_body输出的任意列定义为物化视图的主键。

  • 增量刷新:无论是显式定义主键还是由系统自动定义主键,主键都需满足以下规则:

    • 分组聚合查询(带有GROUP BY的聚合查询),主键必须为GROUP BY列。例如,GROUP BY a,b,主键必须是ab。

    • 非分组聚合查询(无GROUP BY的聚合查询),主键必须为常量。

    • 非聚合查询,主键必须与基表的主键完全相同。例如,基表主键为PRIMARY KEY(sale_id,sale_date),那么物化视图的主键也必须为PRIMARY KEY(sale_id,sale_date)。

使用建议

为了优化物化视图的查询性能,创建物化视图时推荐定义主键、分布键和分区键。

mv_properties

可选参数

创建后是否可变更:通过ALTER MATERIALIZED VIEW变更

仅产品系列为企业版、基础版或湖仓版且3.1.9.3及以上内核版本的集群支持该参数。

定义物化视图的资源策略,包括物化视图使用的资源组(mv_resource_group)和刷新任务的配置参数(mv_refresh_hints)。格式为JSON。示例如下:

MV_PROPERTIES='{
  "mv_resource_group":"<resource_group_name>",
  "mv_refresh_hints":{"<hint_name>":"<hint_value>"}
}'
mv_resource_group

指定资源组用于创建和刷新物化视图。未指定资源组时,将使用默认资源组user_default。

参数取值可以为XIHE引擎的Interactive型资源组或Job型资源组。区别在于Job型资源组需要临时拉起资源,通常有秒级或分钟级的延迟。如果对刷新延迟的容忍度较高,可以指定Job型资源组。使用了Job型资源组的物化视图又叫弹性物化视图。如果想提高弹性物化视图的刷新速度,您可以在mv_refresh_hints中配置elastic_job_max_acu修改物化视图能够使用的最大资源量,用法请参见下文的弹性物化视图示例

您可以在控制台资源组管理页面查看集群有哪些资源组,也可以调用接口DescribeDBResourceGroup查询资源组列表。

若指定的资源组不存在,创建物化视图时会报错。

mv_refresh_hints

物化视图的配置参数。支持配置参数列表和用法,请参见常用Hint

REFRESH [COMPLETE | FAST]

可选参数

默认值:COMPLETE

创建后是否可变更:不可变更

定义物化视图的刷新策略。不同刷新策略的区别和适用场景,请参见如何选择刷新策略

COMPLETE

全量刷新,即每次刷新时运行原始的查询SQL,扫描基表的全部目标分区的数据,用计算好的新数据全量覆盖旧数据。

全量刷新支持的刷新触发机制包括ON DEMAND [START WITH date] [NEXT date]ON OVERWRITE,即可以按需手动刷新,也可以按需定时自动刷新,还可以当基表被覆盖写时自动刷新。

FAST
3.1.9.0及以上版本支持该参数。其中,3.1.9.0版本仅支持增量刷新的单表物化视图;3.2.0.0及以上版本支持增量刷新的单表物化视图和多表物化视图。

增量刷新,即改写物化视图的查询(query_body),使物化视图只扫描基表变更的部分数据,加工后写入物化视图,从而避免每次都扫描基表的全部数据,降低单次刷新的计算开销。

创建增量刷新的物化视图前,需要开启集群的Binlog特性和基表的Binlog功能。否则创建物化视图时会报错。如何开启,请参见开启Binlog特性

增量刷新的物化视图,刷新触发机制必须为定时自动刷新。您需定义下次刷新时间,即ON DEMAND {NEXT date}间。

增量刷新的物化视图存在部分使用限制。当query_body不支持增量刷新时,物化视图的创建会报错。

ON [DEMAND | OVERWRITE]

可选参数

默认值:DEMAND

创建后是否可变更:不可变更

定义物化视图的刷新触发机制。不同触发机制的区别与适用场景,请参见如何选择刷新触发机制

DEMAND

按需刷新。即您可以在需要刷新物化视图时手动触发刷新,或通过NEXT指定定时自动触发刷新。

增量刷新的物化视图,仅支持ON DEMAND

OVERWRITE

物化视图的基表在执行INSERT OVERWRITE语句导致数据被覆盖后,刷新物化视图。

刷新触发机制为ON OVERWRITE时,不能定义START WITHNEXT

[START WITH date] [NEXT date]

可选参数

创建后是否可变更:不可变更

当物化视图的刷新触发机制为ON DEMAND时,可以定义物化视图的刷新时间。如未定义,则不会定时刷新。

START WITH

物化视图的首次刷新时间。若不填,则首次刷新时间为创建物化视图的时间点。

NEXT

物化视图的下次刷新时间。

  • 增量刷新的物化视图,必须定义NEXT,且自动刷新间隔最短5秒(s),最长5分钟(min)。

  • 全量刷新的物化视图,不要求必须定义NEXT,如果定义的话,自动刷新间隔最短60秒(s)。

date

支持使用时间函数,但只支持精确到秒,毫秒部分会被截断。

[DISABLE | ENABLE] QUERY REWRITE

可选参数

默认值:DISABLE

创建后是否可变更:通过ALTER MATERIALIZED VIEW变更

3.1.4及以上版本支持该参数。

是否开启查询改写功能。查询改写的详细介绍,请参见物化视图的查询改写

DISABLE

关闭当前物化视图的查询改写功能。

ENABLE

开启当前物化视图的查询改写功能。开启后,优化器会根据SQL Pattern,改写全部或者部分查询并路由到物化视图上,从而无需在基表执行全部原始计算,提升查询性能。

query_body

必选参数

创建后是否可变更:不可变更

定义物化视图的基表查询。

全量刷新的物化视图,基表可以是AnalyticDB for MySQL内表、外表、已有的物化视图和视图。基表的查询没有限制。查询语法,可以参考SELECT

增量刷新的物化视图,基表只能是AnalyticDB for MySQL内表。基表的查询有以下规则:

SELECT输出列

  • 分组聚合查询(带GROUP BY的聚合查询),SELECT的输出列必须包含GROUP BY子句中的所有分组列。

    点击查看示例

    正确示例

    错误示例

    CREATE MATERIALIZED VIEW demo_mv1
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT 
      sale_id, -- 输出分组列
      sale_date, -- 输出分组列
      max(quantity) AS max, --表达式列必须设置别名
      sum(price)AS sum
    FROM sales
    GROUP BY sale_id,sale_date;
    CREATE MATERIALIZED VIEW false_mv1
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT 
      sale_id, -- 未输出分组列sale_date
      max(quantity) AS max,
      sum(price)AS sum
    FROM sales
    GROUP BY sale_id,sale_date;
  • 非分组聚合查询(不带GROUP BY的聚合查询),SELECT仅输出常量列与聚合列或仅输出聚合列。

    点击查看示例

    正确示例

    错误示例

    只输出聚合列maxsum

    CREATE MATERIALIZED VIEW demo_mv2
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT 
      max(quantity) AS max, --表达式列必须设置别名
      sum(price)AS sum
    FROM sales;

    输出了常量列和聚合列以外的其他列。

    CREATE MATERIALIZED VIEW false_mv2
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT
      sale_id, 
      max(quantity) AS max,
      sum(price) AS sum
    FROM sales;

    输出常量列pk、聚合列maxsum

    CREATE MATERIALIZED VIEW demo_mv3
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT 
      1 AS pk,  -- 非分组聚合中,常量列将作为物化视图的主键
      max(quantity) AS max,
      sum(price) AS sum
    FROM sales;
  • 非聚合查询,SELECT必须输出基表的所有主键列。

    点击查看示例

    正确示例

    错误示例

    CREATE MATERIALIZED VIEW demo_mv4
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT 
      sale_id, --输出基表的主键列
      quantity
    FROM sales;
    CREATE MATERIALIZED VIEW false_mv3
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT 
      sale_date, --未输出基表的主键列sale_id
      quantity
    FROM sales;

    假设表sales1存在复合主键PRIMARY KEY(sale_id,sale_date)。

    CREATE MATERIALIZED VIEW demo_mv5
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT 
      sale_id, --输出基表的主键列
      sale_date, --输出基表的主键列
      quantity
    FROM sales1;

    假设表sales1存在复合主键PRIMARY KEY(sale_id,sale_date)。

    CREATE MATERIALIZED VIEW false_mv4
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT 
      sale_id, --未输出基表的另一个主键列sale_date
      quantity
    FROM sales1;
  • 输出的表达式列必须定义别名。建议使用具有实际意义的别名,例如SUM(price) AS total_price

其他限制

  • 不支持非确定性的表达式,如:NOW()、RAND()等。

  • 不支持ORDER BY排序操作。

  • 不支持HAVING子句。

  • 不支持窗口函数。

  • 不支持UNION、EXCEPT、INTERSECT等集合操作。

  • JOIN操作仅支持INNER JOIN。关联字段须满足所有条件:须为表的原始字段,数据类型须相同,且有INDEX索引。最多关联5张表。

    如需关联更多表,请提交工单联系技术支持。
  • 仅支持以下聚合函数:COUNT、SUM、MAX、MIN、AVG、APPROX_DISTINCTCOUNT(DISTINCT)。

  • AVG不支持DECIMAL类型。

  • COUNT(DISTINCT)仅支持INTEGER类型。

权限要求

创建物化视图的用户需要具备以下所有权限:

  • 物化视图所在数据库的创建表的权限(CREATE权限)。

  • 物化视图所有基表的相关列(或整个表)的SELECT权限。

  • 如需创建自动刷新的物化视图,还需要具备以下两个权限:

    • 从任意IP(即'%')连接AnalyticDB for MySQL的权限。

    • 物化视图或物化视图所在数据库所有表的INSERT权限,否则物化视图中的数据无法刷新。

示例

示例准备

下文的物化视图示例均利用本章节的基表。为了更方便地体验下文的示例,您可以先参考本章节的SQL语句创建基表。

/*+ RC_DDL_ENGINE_REWRITE_XUANWUV2=false */ -- 指定表的引擎为XUANWU引擎。
CREATE TABLE customer (
    customer_id INT PRIMARY KEY,
    customer_name VARCHAR(255),
    is_vip Boolean
);
/*+ RC_DDL_ENGINE_REWRITE_XUANWUV2=false */ -- 指定表的引擎为XUANWU引擎。
CREATE TABLE sales (
    sale_id INT PRIMARY KEY,
    product_id INT,
    customer_id INT,
    price DECIMAL(10, 2),
    quantity INT,
    sale_date TIMESTAMP
);

全量刷新物化视图

  • 创建物化视图myview1,每5分钟刷新一次。

    CREATE MATERIALIZED VIEW myview1
    REFRESH   --等同于REFRESH COMPLETE
     NEXT now() + INTERVAL 5 minute
    AS
    SELECT count(*) as cnt FROM customer;
  • 创建物化视图myview2,每天凌晨2点刷新。

    CREATE MATERIALIZED VIEW myview2
    REFRESH COMPLETE
     START WITH DATE_FORMAT(now() + INTERVAL 1 day, '%Y-%m-%d 02:00:00')
     NEXT DATE_FORMAT(now() + INTERVAL 1 day, '%Y-%m-%d 02:00:00')
    AS
    SELECT count(*) as cnt FROM customer;
  • 创建物化视图myview3,每周一凌晨2点刷新。

    CREATE MATERIALIZED VIEW myview3
    REFRESH COMPLETE ON DEMAND
     START WITH DATE_FORMAT(now() + INTERVAL 7 - weekday(now()) day, '%Y-%m-%d 02:00:00') 
     NEXT DATE_FORMAT(now() + INTERVAL 7 - weekday(now()) day, '%Y-%m-%d 02:00:00')
    AS
    SELECT count(*) as cnt FROM customer;
  • 创建物化视图myview4,每个月第一天凌晨2点刷新。

    CREATE MATERIALIZED VIEW myview4
    REFRESH   --等同于REFRESH COMPLETE 
     NEXT DATE_FORMAT(last_day(now()) + INTERVAL 1 day, '%Y-%m-%d 02:00:00')
    AS
    SELECT count(*) as cnt FROM customer;
  • 创建物化视图myview5,只刷新一次。

    CREATE MATERIALIZED VIEW myview5
    REFRESH   --等同于REFRESH COMPLETE
     START WITH now() + INTERVAL 1 day
    AS 
    SELECT count(*) as cnt FROM customer;
  • 创建物化视图myview6,不自动刷新,完全依靠手动刷新。

    CREATE MATERIALIZED VIEW myview6 (
      PRIMARY KEY (customer_id)
    ) DISTRIBUTED BY HASH (customer_id)
    AS
    SELECT customer_id FROM customer;
  • 创建物化视图myview7,基表被INSERT OVERWRITE覆写后触发物化视图自动刷新。

    CREATE MATERIALIZED VIEW myview7
    REFRESH COMPLETE ON OVERWRITE
    AS
    SELECT count(*) as cnt FROM customer;

增量刷新单表物化视图

创建增量刷新的物化视图前,请先开启集群的Binlog特性和基表的Binlog功能。
SET ADB_CONFIG BINLOG_ENABLE=true;
ALTER TABLE customer binlog=true;
ALTER TABLE sales binlog=true;
  • 创建无聚合操作的增量刷新的单表物化视图fast_mv1,每10秒钟刷新一次,

    CREATE MATERIALIZED VIEW fast_mv1
    REFRESH FAST NEXT now() + INTERVAL 10 second
    AS
    SELECT sale_id, sale_date, price
    FROM sales
    WHERE price > 10;
  • 创建分组聚合操作的增量刷新的单表物化视图fast_mv2,每5秒钟刷新一次。

    CREATE MATERIALIZED VIEW fast_mv2
    REFRESH FAST NEXT now() + INTERVAL 5 second
    AS
    SELECT
       customer_id, sale_date,                 -- 系统会自动输出GROUP BY列作为物化视图主键。
       COUNT(sale_id) AS cnt_sale_id,          -- 聚合输出列。
       SUM(price * quantity) AS total_revenue, -- 聚合输出列。
       customer_id / 100 AS new_customer_id    -- 非聚合输出列可以使用任意表达式。
    FROM sales
    WHERE ifnull(price, 1) > 0                 -- 条件可以使用任何表达式。
    GROUP BY customer_id, sale_date;
  • 创建无分组聚合操作的增量刷新的单表物化视图fast_mv3,每分钟刷新一次。

    CREATE MATERIALIZED VIEW fast_mv3
    REFRESH FAST NEXT now() + INTERVAL 1 minute
    AS
    SELECT count(*) AS cnt   -- 系统会自动生成常量主键,确保全局只有一条记录在物化视图中。
    FROM sales;

增量刷新多表物化视图

  • 创建无聚合操作的增量刷新的多表物化视图fast_mv4,每5秒钟刷新一次,

    CREATE MATERIALIZED VIEW fast_mv4
    REFRESH FAST NEXT now() + INTERVAL 5 second
    AS
    SELECT 
        c.customer_id,
        c.customer_name,
        s.sale_id,
        (s.price * s.quantity) AS revenue
    FROM 
        sales s
    JOIN 
        customer c ON s.customer_id = c.customer_id;
  • 创建分组聚合操作的增量刷新的多表物化视图fast_mv5,每10秒钟刷新一次。

    CREATE MATERIALIZED VIEW fast_mv5
    REFRESH FAST NEXT now() + INTERVAL 10 second
    AS
    SELECT 
        s.sale_id,
        c.customer_name,
        COUNT(*) AS cnt,           
        SUM(s.price * s.quantity) AS revenue                
    FROM 
        sales s
    JOIN 
        (SELECT customer_id, customer_name FROM customer) c ON c.customer_id = s.customer_id
    GROUP BY 
        s.sale_id, c.customer_name;

显式定义主键、分布键、分区键、索引等

  • 创建物化视图myview8,不对全部列建立索引,仅对指定列customer_name建立索引。

    CREATE MATERIALIZED VIEW myview8 (
      INDEX (sale_date),
      PRIMARY KEY (sale_id)
    ) DISTRIBUTED BY HASH (sale_id)
    REFRESH
     NEXT now() + INTERVAL 1 DAY
    AS
    SELECT * FROM sales;
  • 创建物化视图myview9,定义主键、分布键、分区键、聚集索引、指定列索引和注释。

    CREATE MATERIALIZED VIEW myview9 (
      quantity INT,    --即使不显式列出普通列,物化视图也会包含查询中输出的所有列。     
      price DECIMAL(10, 2),
      KEY INDEX_ID(customer_id) COMMENT 'customer',
      CLUSTERED KEY INDEX(sale_id),
      PRIMARY KEY(sale_id,sale_date)
    ) 
    DISTRIBUTED BY HASH(sale_id)
    PARTITION BY VALUE(date_format(sale_date, "%Y%m%d")) LIFECYCLE 30
    COMMENT 'MATERIALIZED VIEW c'
    AS 
    SELECT * FROM sales;

弹性物化视图

  • 创建弹性物化视图myview10,使用Job型资源组serverless创建和刷新物化视图,每天刷新1次。

    CREATE MATERIALIZED VIEW myview10
    MV_PROPERTIES='{
      "mv_resource_group":"serverless"
    }'
    REFRESH COMPLETE ON DEMAND
     START WITH now()
     NEXT now() + INTERVAL 1 DAY
    AS
    SELECT * FROM sales;
  • 创建弹性物化视图myview11,使用Job型资源组serverless创建和刷新物化视图,且可占用serverless资源组12 ACU的资源。

    CREATE MATERIALIZED VIEW myview11
    MV_PROPERTIES='{
      "mv_resource_group":"serverless",
      "mv_refresh_hints":{"elastic_job_max_acu":"12"}
    }'
    REFRESH COMPLETE ON DEMAND
     START WITH now()
     NEXT now() + INTERVAL 1 DAY
    AS
    SELECT * FROM sales;

相关文档

  • 本页导读 (1)
  • 语法
  • 参数说明
  • OR REPLACE
  • mv_definition
  • mv_properties
  • REFRESH [COMPLETE | FAST]
  • ON [DEMAND | OVERWRITE]
  • [START WITH date] [NEXT date]
  • [DISABLE | ENABLE] QUERY REWRITE
  • query_body
  • SELECT输出列
  • 权限要求
  • 示例
  • 示例准备
  • 全量刷新物化视图
  • 增量刷新单表物化视图
  • 增量刷新多表物化视图
  • 显式定义主键、分布键、分区键、索引等
  • 弹性物化视图
  • 相关文档