複数テーブルの結合および複雑な集約操作は、多大な計算リソースと時間を消費する可能性があります。AnalyticDB for MySQL のマテリアライズドビューは、ユーザー定義クエリの結果を事前計算および保存することで、この問題に対処します。クエリを実行すると、AnalyticDB for MySQL はマテリアライズドビューから事前に計算された結果を直接読み取ることで、応答時間を向上させることができます。このトピックでは、マテリアライズドビューの作成方法について説明します。
前提条件
カーネルバージョンが 3.1.3.4 以降である必要があります。
マイナーバージョンの確認および更新を行うには、AnalyticDB for MySQL コンソールの 構成情報 セクションに移動してください(クラスター情報 ページ内)。
マテリアライズドビューの作成
必要な権限
マテリアライズドビューを作成するには、以下のすべての権限が必要です:
マテリアライズドビューを作成するデータベース内のテーブルに対する CREATE 権限。
マテリアライズドビューで参照されるすべての基底テーブルの特定列または全列に対する SELECT 権限。
自動更新可能なマテリアライズドビューを作成する場合は、さらに以下の権限も必要です:
'%'(任意の IP アドレス)への接続権限(AnalyticDB for MySQL 内)。マテリアライズドビュー自体、またはマテリアライズドビューが存在するデータベース内のすべてのテーブルに対する INSERT 権限。この権限がない場合、マテリアライズドビューの更新はできません。
基底テーブルの準備
本セクションでは、customer テーブルと sales テーブルを例として使用し、マテリアライズドビューの作成手順を説明します。
/*+ 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 はデフォルトのインタラクティブリソースグループのコンピューティングリソースを使用してマテリアライズドビューを作成および更新します。インタラクティブリソースグループとジョブリソースグループの違いについて、またはジョブリソースグループの使用方法については、「弾性リソースを使用したマテリアライズドビューの作成または更新」をご参照ください。
完全更新をサポートするマテリアライズドビューの作成
完全更新をサポートするマテリアライズドビュー(完全マテリアライズドビューとも呼ばれます)を作成できます。これらのビューは、AnalyticDB for MySQL の内部テーブルおよび外部テーブル、既存のマテリアライズドビュー、およびビューに基づいて作成できます。
このトピックでは、join_mv という名前のフルリフレッシュ マテリアライズドビューを、customer および sales のベーステーブルを使用して作成する方法について説明し、その後、マテリアライズドビューを手動リフレッシュ用に設定します。
CREATE MATERIALIZED VIEW join_mv
REFRESH COMPLETE ON DEMAND
AS
SELECT
sale_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; を実行します。
高速更新をサポートするマテリアライズドビューの作成
増分更新をサポートする増分マテリアライズドビューを、AnalyticDB for MySQL の内部テーブルに基づいて作成できます。
本セクションでは、複数の結合テーブルに基づく高速マテリアライズドビューの作成方法を説明します。
増分マテリアライズドビューを作成する前に、以下の準備を行ってください:
クラスターが AnalyticDB for MySQL V3.1.9.0 以降を実行していることを確認します。
クラスター全体および各基底テーブルでバイナリログを有効化します。
基底テーブルのバイナリログ有効化に失敗した場合は、「クエリ実行エラー:FAST マテリアライズドビューを作成できません。demotable は増分データの取得をサポートしていません」をご参照ください。
SET ADB_CONFIG BINLOG_ENABLE=true; ALTER TABLE customer binlog=true; ALTER TABLE sales binlog=true;
sales_mv_incre という名前の高速マテリアライズドビューを作成します。このビューは sales テーブルからのみデータを計算します。
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;クラスターが AnalyticDB for MySQL V3.2.1.0 以降を実行している場合、join_mv_incre という名前の複数テーブル対応の高速マテリアライズドビューを 3 分ごとの自動更新で作成することもできます。
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;構文およびその他の例については、「CREATE MATERIALIZED VIEW」をご参照ください。
作成中のマテリアライズドビューの表示
現在作成中のマテリアライズドビューを一覧表示するには、SHOW PROCESSLIST WHERE info LIKE '%CREATE MATERIALIZED VIEW%'; を実行します。
結果の各行は、現在作成中のマテリアライズドビューを表します。user フィールドには、ビューの作成に使用されたデータベースアカウントが表示されます。status フィールドには、現在のステータスが表示されます。Info フィールドには、完全な CREATE 文が含まれます。これらのフィールドの詳細については、「SHOW PROCESSLIST」をご参照ください。
SHOW PROCESSLIST が行を返さない場合、マテリアライズドビューの作成(テーブルスキーマおよび初期データのロードを含む)が完了しています。
マテリアライズドビュー作成時の基底テーブルクエリの記述
完全マテリアライズドビューの基底テーブルクエリ
完全マテリアライズドビューは、AnalyticDB for MySQL の内部テーブルおよび外部テーブル、既存のマテリアライズドビュー、およびビューから作成できます。基底テーブルクエリには制限はありません。クエリ構文の詳細については、「SELECT」をご参照ください。
増分マテリアライズドビューの基底テーブルクエリ
増分更新をサポートするマテリアライズドビューの場合、基底テーブルは AnalyticDB for MySQL の内部テーブルである必要があります。基底テーブルに対するクエリは、以下のルールに準拠している必要があります:
SELECT 列
クエリに集計関数と GROUP BY 句が含まれる場合、SELECT リストには GROUP BY 句のすべての列を含める必要があります。
クエリに集計関数が含まれるが GROUP BY 句が含まれない場合、SELECT リストには定数および集計列のみ、または集計列のみを含めることができます。
クエリで集計を使用しない場合、SELECT リストには基底テーブルのすべてのプライマリキー列を含める必要があります。
UNION ALL クエリでは集計関数はサポートされません。各入力ブランチは「union_all_marker」という名前の列を出力する必要があります。この列は定数である必要があり、各ブランチは異なる定数値を使用する必要があります。そうでないと、データの正確性が保証されません。SELECT リストには基底テーブルのすべてのプライマリキー列を含める必要があります。マテリアライズドビューのプライマリキーには、基底テーブルのプライマリキー列と 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)を使用してください。
その他の制限事項
弾性リソースを使用したマテリアライズドビューの作成または更新
弾性リソースとは、ジョブリソースグループ内のコンピューティングリソースを指します。マテリアライズドビューの作成および更新にはクラスターのコンピューティングリソースが消費されます。MV_PROPERTIES='{"mv_resource_group":"rg_name"}' を使用してリソースグループを指定しない場合、AnalyticDB for MySQL はデフォルトのインタラクティブリソースグループ(名前:user_default)の予約済みコンピューティングリソースを使用してマテリアライズドビューを作成および更新します。
マテリアライズドビューの作成時にジョブリソースグループを指定した場合、そのグループは作成時およびその後の更新時にも使用されます。「"mv_refresh_hints":{"elastic_job_max_acu":"value"}」を使用して、利用可能な最大リソースを定義することもできます。使用方法の詳細については、「mv_properties」をご参照ください。
ジョブリソースグループはインタラクティブリソースグループとは異なります。ジョブリソースグループでは、事前にリソースを購入する必要がないため、無駄を避けコストを削減できます。ただし、各更新時にジョブリソースグループがオンデマンドでコンピューティングリソースをプロビジョニングする必要があるため、更新パフォーマンスはインタラクティブリソースグループよりも低くなります。このプロセスには数秒から数分かかることがあります。
クラスターが以下の両方の条件を満たす場合、弾性リソースを使用できます:
クラスターが Enterprise Edition、Basic Edition、または Data Lakehouse Edition である。
クラスターが AnalyticDB for MySQL V3.1.9.3 以降を実行している。
ジョブリソースグループ my_job_rg の弾性リソースを使用して、customer テーブルに基づくマテリアライズドビューを高優先度で作成および更新します。
CREATE MATERIALIZED VIEW job_mv
MV_PROPERTIES='{
"mv_resource_group":"my_job_rg",
"mv_refresh_hints":{"query_priority":"HIGH"}
}'
REFRESH COMPLETE ON DEMAND
START WITH now()
NEXT now() + INTERVAL 1 DAY
AS
SELECT * FROM customer;マテリアライズドビューの更新トリガー機構
マテリアライズドビューは、最新の更新後のデータ状態を反映しますが、これは基底テーブルの最新データとは限りません。マテリアライズドビューはクエリごとに自動的に更新されません。データのタイムリー性および正確性を確保するには、以下のいずれかの更新トリガーを設定できます:スケジュールによる自動更新、基底テーブルの上書きによる自動更新、または手動更新です。
マテリアライズドビューを更新する際、その更新ポリシーに応じて完全更新または高速更新が適用されます。
更新トリガーと更新ポリシーの違いおよび使用ケースの詳細については、「マテリアライズドビューの更新」をご参照ください。
制限事項
一般的な制限事項
これらの制限事項は、完全および高速のマテリアライズドビューを含むすべてのマテリアライズドビューに適用されます。
マテリアライズドビューに対して
INSERT、DELETE、UPDATEを実行できません。マテリアライズドビューで参照される基底テーブルまたはその列を削除または名前変更できません。基底テーブルを変更するには、まずマテリアライズドビューを削除する必要があります。
デフォルトでは、AnalyticDB for MySQL クラスターあたりのマテリアライズドビューの最大数は、マイナーバージョンによって異なります:
V3.1.4.7 以降:最大 64 個のマテリアライズドビュー。
V3.1.4.7 より前:最大 8 個のマテリアライズドビュー。
説明上限に達した場合は、技術サポートに連絡して、より高いクォータをリクエストできます。
完全マテリアライズドビューの制限事項
予約ノードの追加または削除を行うと、非同期ジョブが無効化されます。完全更新は非同期ジョブであるため、ノードのスケーリング中は実行できません。高速更新機能には影響ありません。
増分マテリアライズドビューの制限事項
基底テーブルに関する増分マテリアライズドビューの制限事項:
V3.2.6.0 より前のクラスターでは、XUANWU_V2 テーブルを高速マテリアライズドビューの基底テーブルとしてサポートしていません。
XUANWU_V2 テーブルはバイナリログをサポートしていません。
V3.2.3.0 より前のクラスターでは、パーティションテーブルを高速マテリアライズドビューの基底テーブルとしてサポートしていません。
V3.2.3.1 より前のクラスターでは、高速マテリアライズドビューの基底テーブルに対して INSERT OVERWRITE または TRUNCATE をサポートしていません。これらの文はエラーを返します。
クエリで MAX()、MIN()、APPROX_DISTINCT()、COUNT(DISTINCT) を使用する場合、基底テーブルは INSERT のみをサポートします。DELETE、UPDATE、REPLACE、INSERT ON DUPLICATE KEY UPDATE などのデータ削除操作は許可されていません。
V3.2.5.0 以降を実行するクラスターでは、マテリアライズドビューのバイナリログがサポートされています。そのため、マテリアライズドビューを基底テーブルとして使用でき、高速マテリアライズドビューをネストすることが可能です。
更新トリガーに関する制限事項:
スケジュールによる自動更新のみがサポートされており、手動更新はサポートされていません。間隔は 5 秒から 5 分の間である必要があります。
クエリ本文(query_body)に関する制限事項:
NOW() や RAND() などの非決定的式はサポートされていません。
ORDER BY 句はサポートされていません。
HAVING 句はサポートされていません。
ウィンドウ関数はサポートされていません。
UNION、EXCEPT、INTERSECT などの集合演算子はサポートされていません。UNION ALL は V3.2.5.0 以降でサポートされています。
INNER JOIN のみがサポートされています。結合列は、すべて以下の条件を満たす必要があります:基底テーブルの元の列であること、データ型が同一であること、インデックスが設定されていること。最大 5 つの基底テーブルを結合できます。
それ以上のテーブルを関連付けるには、して技術サポートにお問い合わせください。
サポートされる集計関数は、COUNT、SUM、MAX、MIN、AVG、APPROX_DISTINCT、COUNT(DISTINCT) のみです。
AVG は DECIMAL 型をサポートしていません。
COUNT(DISTINCT) は INTEGER 型のみをサポートしています。
よくある質問
マテリアライズドビューに直近 1 年分のデータのみを保持するにはどうすればよいですか?
マテリアライズドビューを定義する際に、日付列をパーティションキー(PARTITION BY)として使用し、ライフサイクル(LIFECYCLE)を設定して直近 1 年分のデータのみを保持します。
たとえば、sales テーブルに毎日新しいレコードが追加される場合、sale_date 列をパーティションキーとして使用し、LIFECYCLE を 365 に設定できます。これにより、直近 365 個のパーティション(実質的に 1 年分のデータ)のみが保持されます。
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;一般的なエラーとトラブルシューティング
クエリ実行エラー:FAST マテリアライズドビューを作成できません。demotable は増分データの取得をサポートしていません
原因:増分更新をサポートするマテリアライズドビューで使用される基底テーブル demotable でバイナリログが有効化されていません。増分更新をサポートするマテリアライズドビューでは、関与するすべての基底テーブルでバイナリログが有効化されている必要があります。
解決策:基底テーブルのバイナリログを有効化するために、ALTER TABLE demotable binlog=true; を実行します。
エラー XUANWU_V2 engine not support ALTER_BINLOG_ENABLE now を受信した場合、基底テーブル demotable は XUANWU_V2 エンジンを使用しています。XUANWU_V2 はバイナリログをサポートしていません。テーブルのエンジンを変更できないため、XUANWU_V2 を無効化し、XUANWU エンジンを使用してテーブルを再作成し、XUANWU_V2 テーブルから XUANWU テーブルへデータを移行した後、XUANWU テーブル上で高速マテリアライズドビューを作成する必要があります。
XUANWU_V2 を無効化するには:
基底テーブルが DTS、ゼロETL、またはコンソールのデータ同期によって自動作成される場合、クラスター全体で XUANWU_V2 を無効化します。XUANWU_V2 を無効化すると、新しく作成されるすべてのテーブルは XUANWU エンジンを使用します。
クラスター全体で無効化するには:
SET adb_config RC_DDL_ENGINE_REWRITE_XUANWUV2=false;基底テーブルが CREATE TABLE 文で手動作成され、高速マテリアライズドビューに必要なテーブルが少数のみである場合、特定の CREATE TABLE 文で XUANWU_V2 を無効化できます。この場合、その文でのみ XUANWU テーブルが作成され、他の CREATE TABLE 文は引き続き XUANWU_V2 テーブルを作成します。
テーブル単位で無効化するには:
/*+ RC_DDL_ENGINE_REWRITE_XUANWUV2=false */CREATE TABLE ...
クエリ実行エラー:PRIMARY KEY id は MV に出力する必要があります。
原因:高速マテリアライズドビューのクエリは、GROUP BY 句を持たない非集計クエリです。この場合、マテリアライズドビューのプライマリキーは基底テーブルのプライマリキーと一致する必要がありますが、SELECT リストに基底テーブルのプライマリキー列が含まれていません。
誤った例:
CREATE MATERIALIZED VIEW wrong_example1
REFRESH FAST ON DEMAND
NEXT now() + interval 200 second
AS
SELECT product_id,price -- 基底テーブル sales のプライマリキーは sale_id ですが、SELECT に sale_id が含まれていません。
FROM sales;解決策:基底テーブルのプライマリキー列を SELECT リストに追加します。
正しい例:
CREATE MATERIALIZED VIEW correct_example1
REFRESH FAST ON DEMAND
NEXT now() + interval 200 second
AS
SELECT sale_id,product_id, price -- 基底テーブルのプライマリキー sale_id を SELECT に追加します。
FROM sales;クエリ実行エラー:MV PRIMARY KEY は基底テーブル PRIMARY KEY と等しくなければなりません。
原因:高速マテリアライズドビューのクエリは、GROUP BY 句を持たない非集計クエリです。この場合、マテリアライズドビューのプライマリキーは基底テーブルのプライマリキーと一致する必要がありますが、定義に基底テーブルのプライマリキー列と非プライマリキー列の両方が含まれています。
誤った例:
CREATE MATERIALIZED VIEW wrong_example2
(PRIMARY KEY(sale_id,product_id)) -- product_id は基底テーブル sales のプライマリキー列ではありません。
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)) -- product_id をプライマリキーから削除します。
REFRESH FAST ON DEMAND
NEXT now() + interval 200 second
AS
SELECT sale_id,product_id,price
FROM sales;クエリ実行エラー:FAST マテリアライズドビューには PRIMARY KEY を定義する必要があります
原因:このエラーには 2 つの可能性があります:
高速マテリアライズドビューに有効なプライマリキーが定義されていません。
クエリで基底テーブルのプライマリキー列に関数が適用されています。
解決策:適切な修正を選択してください:
有効なプライマリキーが定義されていない場合:マテリアライズドビュー定義(mv_definition)を以下のルールに従って更新します:
グループ化集計クエリ(GROUP BY あり)の場合、プライマリキーは GROUP BY 列である必要があります。たとえば、
GROUP BY a,bの場合、プライマリキーは列 a および b である必要があります。非グループ化集計クエリ(GROUP BY 無し)の場合、プライマリキーは定数である必要があります。
非集計クエリの場合、プライマリキーは基底テーブルのプライマリキーと完全に一致する必要があります。たとえば、基底テーブルのプライマリキーが PRIMARY KEY(sale_id,sale_date) の場合、マテリアライズドビューのプライマリキーも PRIMARY KEY(sale_id,sale_date) である必要があります。
プライマリキー列に関数が適用されている場合:クエリを修正して、基底テーブルのプライマリキー列から関数を削除します。
クエリ実行エラー:サポートされていない結合グラフです。
原因:複数テーブル結合で使用される列のデータ型が一致していないためです。例:sales INNER JOIN customer ON customer.id=sales.id。customer.id と sales.id のデータ型が異なる場合、このエラーが発生します。
解決策:データ型を揃えるために、ALTER TABLE tablename MODIFY COLUMN columnname newtype; を実行します。詳細については、「列のデータ型の変更」をご参照ください。
クエリ実行エラー:この高速 MV の更新にインデックス結合を使用できません。
原因:結合列にインデックスが設定されていません。例:sales INNER JOIN customer ON customer.id=sales.id。customer.id または sales.id のいずれかにインデックスが設定されていない場合、このエラーが発生します。
解決策:結合列にインデックスを追加するために、ALTER TABLE tablename ADD KEY idx_name(columnname); を実行します。詳細については、「インデックスの作成」をご参照ください。
クエリ実行エラー:クエリが予約メモリ制限を超えました
原因:クエリがシングルノードのメモリ制限を超えています。
解決策:メモリを大量に消費する SQL 文は、通常、集約、TopN、ウィンドウ、または結合オペレーターを使用します。SQL 診断 機能を使用して、メモリ使用量の多いステージおよびオペレーターを特定できます。その後、これらのオペレーターを最適化できます。詳細については、「メモリメトリクス」および「ステージおよびタスクの詳細を使用したクエリ分析」をご参照ください。
参照
マテリアライズドビュー:概念、一般的なユースケース、および機能アップデートについて学びます。
CREATE MATERIALIZED VIEW:構文の詳細について学びます。
マテリアライズドビューの更新:更新ポリシー、更新トリガー、および手動更新について学びます。
マテリアライズドビューの管理:定義および更新履歴の照会、すべてのマテリアライズドビューの一覧表示、またはマテリアライズドビューの削除方法について学びます。
マテリアライズドビューからのデータ照会:マテリアライズドビューからデータを照会する方法について学びます。