全部產品
Search
文件中心

AnalyticDB:CREATE MATERIALIZED VIEW

更新時間:Feb 06, 2026

本文介紹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]
[COMMENT 'view_comment']
AS 
query_body

mv_definition:
  ({column_name column_type [column_attributes] [ column_constraints ] [COMMENT 'column_comment']
  | table_constraints}
  [, ... ])
  [table_attribute]
  [partition_options]
  [index_all]
  [storage_policy]
  [block_size]
  [engine]
  [table_properties]

參數說明

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,主鍵必須是a和b。

    • 非分組彙總查詢(無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),使物化視圖只掃描基表變更的部分資料(INSERT、DELETE、UPDATE),加工後寫入物化視圖,從而避免每次都掃描基表的全部資料,降低單次重新整理的計算開銷。

建立增量重新整理的物化視圖前,需要開啟叢集的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_DISTINCT和COUNT(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;

    手動重新整理物化視圖:

    REFRESH MATERIALIZED VIEW myview6;
  • 建立物化視圖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,定義分布鍵和分區鍵。

CREATE MATERIALIZED VIEW myview8 (
  quantity INT,    --即使不顯式列出普通列,物化視圖也會包含查詢中輸出的所有列。     
  price DECIMAL(10, 2),
  sale_date TIMESTAMP
) 
DISTRIBUTED BY HASH(sale_id)
PARTITION BY VALUE(date_format(sale_date, "%Y%m%d")) LIFECYCLE 30
AS 
SELECT * FROM sales;

顯式定義主鍵、分布鍵、索引等

  • 建立物化視圖myview9,不對全部列建立索引,僅對指定列customer_name建立索引。

    CREATE MATERIALIZED VIEW myview9 (
      INDEX (sale_date),
      PRIMARY KEY (sale_id)
    ) DISTRIBUTED BY HASH (sale_id)
    REFRESH
     NEXT now() + INTERVAL 1 DAY
    AS
    SELECT * FROM sales;
  • 建立物化視圖myview10,定義主鍵、分布鍵、叢集索引、指定列索引和注釋。

    CREATE MATERIALIZED VIEW myview10 (
      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)
    COMMENT 'MATERIALIZED VIEW c'
    AS 
    SELECT * FROM sales;

彈性物化視圖

  • 建立彈性物化視圖myview11,使用Job型資源群組serverless建立和重新整理物化視圖,每天重新整理1次。

    CREATE MATERIALIZED VIEW myview11
    MV_PROPERTIES='{
      "mv_resource_group":"serverless"
    }'
    REFRESH COMPLETE ON DEMAND
     START WITH now()
     NEXT now() + INTERVAL 1 DAY
    AS
    SELECT * FROM sales;
  • 建立彈性物化視圖myview12,使用Job型資源群組serverless建立和重新整理物化視圖,且可佔用serverless資源群組12 ACU的資源。

    CREATE MATERIALIZED VIEW myview12
    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;

相關文檔