マテリアライズドビューは、クエリ結果を事前に計算して保存するため、AnalyticDB for MySQL はクエリごとに負荷の高い複数テーブルの結合や集計を再実行する代わりに、これらの結果を直接提供できます。このトピックでは、マテリアライズドビューの作成方法、リフレッシュタイプの選択方法、および一般的なエラーの解決方法について説明します。
前提条件
開始する前に、次のことを確認してください。
クラスターのカーネルバージョンは 3.1.3.4 以降です。バージョンを確認または更新するには、AnalyticDB for MySQL コンソールのクラスター情報 ページにある構成情報 セクションに移動します。
データベースアカウントに必要なすべての権限が付与されていること:
ターゲットデータベース内のテーブルに対する CREATE 権限
マテリアライズドビューが参照するすべてのベーステーブルの全列 (または特定の列) に対する SELECT 権限
自動リフレッシュされるマテリアライズドビューの場合は、さらに以下の権限が必要です:
'%'(任意の IP アドレス) からの接続権限マテリアライズドビューまたはそのデータベース内のすべてのテーブルに対する INSERT 権限
リフレッシュタイプの選択
AnalyticDB for MySQL は、2 種類のリフレッシュタイプをサポートしています。リフレッシュタイプによって、クエリボディで使用できる SQL 機能と、マテリアライズドビューがベーステーブルと同期する方法が決まります。
完全リフレッシュ | 高速 (増分) リフレッシュ | |
仕組み | マテリアライズドビュー内のすべてのデータを置き換えます | 最終リフレッシュ以降の変更のみを適用します |
ベーステーブル | 内部テーブル、外部テーブル、既存のマテリアライズドビュー、およびビュー | 内部テーブルのみ |
SQL サポート | 完全な SELECT 構文 | SELECT のサブセット (「増分 MV のクエリ制約」をご参照ください) |
リフレッシュトリガー | 定時自動リフレッシュ、ベーステーブル上書き時の自動リフレッシュ、または手動リフレッシュ | 定時自動リフレッシュのみ (間隔:5 秒~ 5 分) |
最小バージョン | 3.1.3.4 | 3.1.9.0 (単一テーブル) 、3.2.1.0 (複数テーブル) |
ベーステーブルの準備
このトピックの例では、次の 2 つのテーブルを使用します。マテリアライズドビューの例を実行する前に、これらのテーブルを作成してください。
/*+ 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
);この例では、リソースグループを指定していません。リソースグループが指定されていない場合、AnalyticDB for MySQL はデフォルトのインタラクティブリソースグループを使用して、マテリアライズドビューを作成およびリフレッシュします。代わりにジョブリソースグループを使用するには、「弾性リソースを使用したマテリアライズドビューの作成またはリフレッシュ」をご参照ください。
完全リフレッシュマテリアライズドビューの作成
完全リフレッシュマテリアライズドビューは、完全な SELECT 構文をサポートしており、内部テーブル、外部テーブル、既存のマテリアライズドビュー、およびビューを参照できます。
次の例では、customer と sales を結合し、手動でリフレッシュする join_mv という名前のマテリアライズドビューを作成します。
CREATE MATERIALIZED VIEW join_mv
REFRESH COMPLETE ON DEMAND
AS
SELECT
customer.customer_id,
SUM(price * quantity) AS price
FROM customer
INNER JOIN (SELECT sale_id, customer_id, price, quantity FROM sales) sales
ON customer.customer_id = sales.customer_id
GROUP BY customer.customer_id;ビューを手動でリフレッシュするには、次を実行します。
REFRESH MATERIALIZED VIEW join_mv;高速 (増分) リフレッシュマテリアライズドビューの作成
高速マテリアライズドビューは、最終リフレッシュ以降の変更のみを適用するため、増分的に変更される大規模なデータセットに対してより効率的です。その代わり、サポートされる SQL 機能の範囲が狭くなります。SELECT クエリボディに記述する内容によって、増分リフレッシュが適用されるかどうかが決まります (「増分 MV のクエリ制約」をご参照ください) 。
バージョン要件: 3.1.9.0 以降 (単一テーブル) 、3.2.1.0 以降 (複数テーブル) 。
バイナリロギングの有効化
増分リフレッシュは、ベーステーブルの変更を追跡するためにバイナリロギングに依存します。クラスターレベルと各ベーステーブルで有効にしてください。
SET ADB_CONFIG BINLOG_ENABLE=true;
ALTER TABLE customer binlog=true;
ALTER TABLE sales binlog=true;バイナリロギングの有効化に失敗した場合は、「高速マテリアライズドビューを作成できない」をご参照ください。
単一テーブルの高速マテリアライズドビューの作成
次の例では、sales テーブルに sales_mv_incre という名前の高速マテリアライズドビューを作成し、自動リフレッシュ間隔を 3 分に設定します。
CREATE MATERIALIZED VIEW sales_mv_incre
REFRESH FAST NEXT now() + INTERVAL 3 minute
AS
SELECT
sale_id,
SUM(price * quantity) AS price
FROM sales
GROUP BY sale_id;複数テーブルの高速マテリアライズドビューの作成
V3.2.1.0 以降のクラスターでは、高速マテリアライズドビューで複数のテーブルを結合できます。次の例では、customer と sales を結合します。
CREATE MATERIALIZED VIEW join_mv_incre
REFRESH FAST NEXT now() + INTERVAL 3 minute
AS
SELECT
customer.customer_id,
SUM(sales.price) AS price
FROM customer
INNER JOIN (SELECT customer_id, price FROM sales) sales
ON customer.customer_id = sales.customer_id
GROUP BY customer.customer_id;注意事項
ベーステーブルが TRUNCATE または INSERT OVERWRITE 操作の対象である場合、またはデータの正確性に影響を与える可能性のある内部的な異常が発生した場合、増分マテリアライズドビューは自動的に 1 回限りの完全リフレッシュにフォールバックします。完全リフレッシュが成功した後、後続のリフレッシュは自動的に増分モードで再開されます。
CREATE MATERIALIZED VIEW の完全な構文については、「CREATE MATERIALIZED VIEW」をご参照ください。
作成進捗の監視
CREATE MATERIALIZED VIEW ステートメントには初期データロードが含まれるため、時間がかかる場合があります。次のクエリを実行して、現在作成中のマテリアライズドビューを一覧表示します。
SHOW PROCESSLIST WHERE info LIKE '%CREATE MATERIALIZED VIEW%';各行は、進行中のマテリアライズドビューを表します。User フィールドにはデータベースアカウント、State フィールドには現在のステータス、Info フィールドには完全な CREATE ステートメントが表示されます。フィールドの定義については、「SHOW PROCESSLIST」をご参照ください。
SHOW PROCESSLIST が行を返さなくなると、スキーマと初期データを含むマテリアライズドビューの作成は完了です。
弾性リソースを使用したマテリアライズドビューの作成またはリフレッシュ
デフォルトでは、AnalyticDB for MySQL は、デフォルトのインタラクティブリソースグループ (user_default) の予約済みコンピューティングリソースを使用して、マテリアライズドビューを作成およびリフレッシュします。インタラクティブなワークロードとの競合を避けるために、代わりにジョブリソースグループを使用します。
弾性リソースを使用する場合:
マテリアライズドビューの作成とリフレッシュをインタラクティブなクエリから分離したい場合。
専用リソースを事前に購入することを避けたい場合。
トレードオフ:ジョブリソースグループは、オンデマンドでコンピューティングリソースをプロビジョニングするため、インタラクティブリソースグループと比較して、各リフレッシュの前に数秒から数分の起動オーバーヘッドが追加されます。
クラスター要件:
Enterprise Edition、Basic Edition、または Data Lakehouse Edition
V3.1.9.3 以降
MV_PROPERTIES を使用してジョブリソースグループを指定します。次の例では、ジョブリソースグループ my_job_rg を高い優先度で使用して毎日リフレッシュするマテリアライズドビューを作成します。
CREATE MATERIALIZED VIEW job_mv
MV_PROPERTIES='{
"mv_resource_group": "my_job_rg",
"mv_refresh_hints": {"query_priority": "HIGH"}
}'
REFRESH COMPLETE START WITH now() NEXT now() + INTERVAL 1 DAY
AS
SELECT * FROM customer;リフレッシュ中に使用される最大リソースを制限するには、mv_refresh_hints に "elastic_job_max_acu": "<value>" を追加します。mv_properties オプションの完全なリストについては、「mv_properties」をご参照ください。
リフレッシュトリガーメカニズム
マテリアライズドビューは、ベーステーブルの現在の状態ではなく、最終リフレッシュ時点のデータを反映します。データの鮮度に応じてリフレッシュトリガーを選択してください。
定時自動リフレッシュ:一定の間隔 (例:3 分ごと、毎日) でリフレッシュします。完全リフレッシュと高速リフレッシュの両方でサポートされています。
ベーステーブル上書き時の自動リフレッシュ:ベーステーブルが上書きされたときにリフレッシュをトリガーします。完全リフレッシュでのみサポートされています。
手動リフレッシュ:必要に応じて
REFRESH MATERIALIZED VIEW <view_name>;を実行します。完全リフレッシュでのみサポートされています。
リフレッシュポリシーと手動リフレッシュの構文の詳細については、「マテリアライズドビューのリフレッシュ」をご参照ください。
増分 MV のクエリ制約
高速マテリアライズドビューの SELECT クエリボディには、完全リフレッシュビューには適用されない制約があります。最も重要な制約は次のとおりです。
INNER JOIN のみがサポートされています。結合列はベーステーブルの元の列で、データ型が同じで、インデックスが作成されている必要があります。最大 5 つのベーステーブルを結合できます。
制約によってユースケースが妨げられる場合は、代わりに完全リフレッシュマテリアライズドビューを使用してください。完全リフレッシュマテリアライズドビューは、結合の制限なしで完全な SELECT 構文をサポートします。
サポートされていないSQL機能は、次の表のとおりです。
機能 | サポート状況 | 注意事項 |
内部結合 (複数テーブル) | はい (V3.2.1.0+) | 最大 5 テーブル。結合列にはインデックスが作成され、データ型が一致している必要があります |
UNION ALL | はい (V3.2.5.0+) | 特別なクエリ構造が必要です (下記参照) |
COUNT、SUM、MAX、MIN、AVG、APPROX_DISTINCT、COUNT(DISTINCT) | はい | 他のすべての集計関数はサポートされていません |
DECIMAL 型での AVG | いいえ | 別の数値型を使用してください |
非 INTEGER 型での COUNT(DISTINCT) | いいえ | INTEGER 型のみをサポートします |
ウィンドウ関数 | いいえ | — |
HAVING 句 | いいえ | — |
ORDER BY 句 | いいえ | — |
非決定性式 (NOW()、RAND()) | いいえ | — |
UNION、EXCEPT、INTERSECT | いいえ | UNION ALL は V3.2.5.0 からサポートされています |
ベーステーブルとしての XUANWU_V2 テーブル | いいえ (V3.2.6.0 未満) | XUANWU_V2 は V3.2.6.0 からバイナリロギングをサポートします |
ベーステーブルとしてのパーティションテーブル | いいえ (V3.2.3.0 未満) | — |
ベーステーブルに対する INSERT OVERWRITE または TRUNCATE | いいえ (V3.2.3.1 未満) | エラーを返します |
DELETE/UPDATE/REPLACE/INSERT ON DUPLICATE KEY UPDATE と併用する MAX()、MIN()、APPROX_DISTINCT()、COUNT(DISTINCT) | いいえ | ベーステーブルは INSERT のみをサポートします |
ベーステーブルとしての高速 MV (ネストされた高速 MV) | はい (V3.2.5.0+) | マテリアライズドビューでバイナリロギングを有効にする必要があります |
高速マテリアライズドビューで 5 つ以上のテーブルを結合するには、。
SELECT 列のルール
SELECT リストの列は、次のルールに従う必要があります。
GROUP BY と集計関数を使用する場合: SELECT リストにすべての GROUP BY 列を含めてください。
集計関数を使用し、GROUP BY を使用しない場合: SELECT リストには、集計列のみ、または定数と集計列のみを含めることができます。
集計を使用しない場合:ベーステーブルのすべてのプライマリキー列を含めてください。
UNION ALL クエリ:各ブランチは、ブランチごとに異なる定数値を持つ
union_all_markerという名前の列を出力する必要があります。すべてのベーステーブルのプライマリキー列を含めます。マテリアライズドビューのプライマリキーには、ベーステーブルのプライマリキー列とunion_all_markerの両方を含める必要があります。CREATE MATERIALIZED VIEW demo_union_all_mv (PRIMARY KEY(id, union_all_marker)) REFRESH FAST NEXT now() + INTERVAL 5 minute AS SELECT customer_id AS id, "customer" AS union_all_marker FROM customer UNION ALL SELECT sale_id AS id, "sales" AS union_all_marker FROM sales;式の列: SELECT リスト内のすべての式の列には、
SUM(price) AS total_priceのようにエイリアスが必要です。
制限
一般的な制限
これらの制限は、すべてのマテリアライズドビューに適用されます。
マテリアライズドビューに対して INSERT、DELETE、または UPDATE を実行することはできません。
マテリアライズドビューが参照している間は、ベーステーブルまたはその列を削除したり名前を変更したりすることはできません。まずマテリアライズドビューを削除してから、ベーステーブルを変更してください。
クラスターあたりの最大マテリアライズドビュー数:
V3.1.4.7 以降:64
V3.1.4.7 未満:8
クォータを引き上げるには、。
完全リフレッシュマテリアライズドビューの制限
予約済みノードを追加または削除すると、非同期ジョブは無効になります。完全リフレッシュは非同期ジョブであるため、ノードのスケーリング中は実行できません。高速リフレッシュは影響を受けません。
高速 (増分) リフレッシュマテリアライズドビューの制限
SQL の制限の完全なリストについては、「増分 MV のクエリ制約」をご参照ください。
リフレッシュトリガー:定時自動リフレッシュのみがサポートされています。間隔は 5 秒から 5 分の間でなければなりません。
増分マテリアライズドビューにおける複数テーブル結合の制限:
最大 5 つのベーステーブルを結合できます。
この制限の緩和については、クラスターの仕様に基づいて。
INNER JOIN のみがサポートされています。
結合列はベーステーブルの元の列であり、データ型が同じで、インデックスが作成されている必要があります。
よくある質問
マテリアライズドビューに最新の 1 年分のデータのみを保持するにはどうすればよいですか?
日付列をパーティションキー (PARTITION BY) として使用して、LIFECYCLE 値を設定し保持するパーティションの数を制限します。日付でパーティション化されたビューの場合は、LIFECYCLE 365 を設定すると、最新の 365 パーティション (1 年分) が保持されます。
例:sales テーブルに、sale_date でパーティション化された新しいレコードが毎日追加されます。
CREATE MATERIALIZED VIEW sales_mv_lifecycle
PARTITION BY VALUE(DATE_FORMAT(sale_date, '%Y%m%d')) LIFECYCLE 365
REFRESH FAST NEXT now() + INTERVAL 100 second
AS
SELECT
sale_date,
SUM(price * quantity) AS price
FROM sales
GROUP BY sale_date;トラブルシューティング
クエリ実行エラー:Can not create FAST materialized view, because demotable doesn't support getting incremental data
ベーステーブル demotable でバイナリロギングが有効になっていません。次のコマンドで有効にしてください。
ALTER TABLE demotable binlog=true;XUANWU_V2 engine not support ALTER_BINLOG_ENABLE now と表示された場合、ベーステーブルは XUANWU_V2 エンジンを使用しており、クラスターのカーネルバージョンは V3.2.6.0 未満です。XUANWU_V2 は、カーネルバージョン V3.2.6.0 からバイナリロギングをサポートします。クラスターを V3.2.6.0 以降にアップグレードし、再度 ALTER TABLE demotable binlog=true; を実行してベーステーブルでバイナリロギングを有効にしてください。
クエリ実行エラー:PRIMARY KEY id must output to MV
高速マテリアライズドビューが GROUP BY のない非集計クエリを使用しています。この場合、SELECT リストにはベーステーブルのすべてのプライマリキー列を含める必要があります。
正しくない例 (sales のプライマリキーである sale_id がありません) :
CREATE MATERIALIZED VIEW wrong_example1
REFRESH FAST ON DEMAND
NEXT now() + interval 200 second
AS
SELECT product_id, price
FROM sales;プライマリキー列を追加してください。
CREATE MATERIALIZED VIEW correct_example1
REFRESH FAST ON DEMAND
NEXT now() + interval 200 second
AS
SELECT sale_id, product_id, price
FROM sales;クエリ実行エラー:MV PRIMARY KEY must be equal to base table PRIMARY KEY
高速マテリアライズドビューが GROUP BY のない非集計クエリを使用しており、マテリアライズドビューのプライマリキー定義に、ベーステーブルのプライマリキーの一部ではない列が含まれています。
正しくない例 (product_id は sales のプライマリキー列ではありません) :
CREATE MATERIALIZED VIEW wrong_example2
(PRIMARY KEY(sale_id, product_id))
REFRESH FAST ON DEMAND
NEXT now() + interval 200 second
AS
SELECT sale_id, product_id, price
FROM sales;プライマリキー定義からプライマリキー以外の列を削除してください。
CREATE MATERIALIZED VIEW correct_example2
(PRIMARY KEY(sale_id))
REFRESH FAST ON DEMAND
NEXT now() + interval 200 second
AS
SELECT sale_id, product_id, price
FROM sales;クエリ実行エラー:FAST materialized view must define PRIMARY KEY
このエラーには 2 つの原因が考えられます。
有効なプライマリキーが定義されていません。 マテリアライズドビューの定義を更新して、次のルールを満たすようにしてください。
グループ化された集計クエリ (GROUP BY を使用) :プライマリキーは GROUP BY 列でなければなりません (例:
GROUP BY a, bの場合、PRIMARY KEY(a, b)を設定) 。グループ化されていない集計クエリ (GROUP BY を使用しない) :プライマリキーは定数でなければなりません。
非集計クエリ:プライマリキーはベーステーブルのプライマリキーと完全に一致する必要があります (例:ベーステーブルに
PRIMARY KEY(sale_id, sale_date)がある場合、ビューにもPRIMARY KEY(sale_id, sale_date)が必要) 。
プライマリキー列に関数が適用されています。 クエリ内のプライマリキー列から関数を削除してください。
クエリ実行エラー:The join graph is not supported
結合列のデータ型が一致していません。たとえば、customer.id と sales.id の型が異なる場合、結合は失敗します。次のコマンドで型を揃えてください。
ALTER TABLE tablename MODIFY COLUMN columnname newtype;詳細については、「列のデータ型の変更」をご参照ください。
クエリ実行エラー:Unable to use index join to refresh this fast MV
結合列にインデックスがありません。各結合列にインデックスを追加してください。
ALTER TABLE tablename ADD KEY idx_name(columnname);詳細については、「インデックスの作成」をご参照ください。
クエリ実行エラー:Query exceeded reserved memory limit
クエリがノードごとのメモリ制限を超えました。SQL 診断機能を使用して、メモリ使用量の多いステージと演算子 (Aggregation、TopN、Window、Join が一般的な原因です) を特定し、それらの演算子を最適化してください。「メモリメトリック」および「ステージとタスクの詳細を使用したクエリの分析」もご参照ください。
次のステップ
マテリアライズドビュー — 概念、ユースケース、機能の更新
CREATE MATERIALIZED VIEW — 完全な構文リファレンス
マテリアライズドビューのリフレッシュ — リフレッシュポリシー、トリガー、手動リフレッシュ
マテリアライズドビューの管理 — クエリ定義、リフレッシュ履歴、一覧表示、削除
マテリアライズドビューからのデータクエリ — クエリ構文と例