多くの場合、複数テーブルの結合と複雑な集約操作は時間がかかり、大量の計算資源を必要とします。この問題を解決するために、AnalyticDB for MySQLはマテリアライズドビューを提供します。マテリアライズドビューは、ユーザー定義のクエリを事前に計算し、クエリ結果を保存します。クエリを実行すると、AnalyticDB for MySQL は保存されたクエリ結果をマテリアライズドビューから読み取り、クエリの応答時間を改善します。このトピックでは、マテリアライズドビューを作成する方法について説明します。
前提条件
V3.1.3.4 以降の AnalyticDB for MySQL クラスタが作成されていること。
マテリアライズドビューの作成
必要な権限
マテリアライズドビューを作成する前に、以下のすべての権限を持っていることを確認してください。
マテリアライズドビューを作成するデータベース内のテーブルに対する CREATE 権限。
マテリアライズドビューで参照されるすべてのベーステーブルの特定またはすべての列に対する SELECT 権限。
自動的にリフレッシュできるマテリアライズドビューを作成する場合、以下の権限も必要です。
AnalyticDB for MySQL に
'%'で示される任意の IP アドレスから接続するための権限。マテリアライズドビューまたはマテリアライズドビューが存在するデータベース内のすべてのテーブルに対する INSERT 権限。そうでない場合、マテリアライズドビューのデータをリフレッシュできません。
ベーステーブルの準備
customer と sales という名前の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 はデフォルトのインタラクティブリソースグループの計算資源を使用して、マテリアライズドビューを作成およびリフレッシュします。マテリアライズドビューの作成およびリフレッシュ時のインタラクティブリソースグループとジョブリソースグループの違い、またはジョブリソースグループを使用したマテリアライズドビューの作成およびリフレッシュ方法については、このトピックの「Elastic リソースを使用してマテリアライズドビューを作成またはリフレッシュする」セクションを参照してください。
完全リフレッシュをサポートするマテリアライズドビューを作成する
AnalyticDB for MySQL の内部テーブルと外部テーブル、既存のマテリアライズドビュー、およびビューに基づいて、完全リフレッシュをサポートするマテリアライズドビュー(以下、完全マテリアライズドビュー)を作成できます。
リフレッシュトリガーメカニズムを手動リフレッシュに設定し、customer テーブルと sales テーブルに基づいて、join_mv という名前の完全マテリアライズドビューを作成します。
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 クラスタのマイナーバージョンが 3.1.9.0 以降であることを確認します。
クラスタとベーステーブルのバイナリロギング機能を有効にします。
ベーステーブルのバイナリロギング機能を有効にする際にエラーが発生した場合は、このトピックの「クエリ実行エラー: : Can not create FAST materialized view, because demotable doesn't support getting incremental data」セクションを参照して、この問題を解決してください。
SET ADB_CONFIG BINLOG_ENABLE=true; ALTER TABLE customer binlog=true; ALTER TABLE sales binlog=true;
sales テーブルに基づいて、sales_mv_incre という名前の高速マテリアライズドビューを作成します。
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 クラスタのマイナーバージョンが 3.2.1.0 以降の場合は、結合された customer テーブルと sales テーブルに基づいて、リフレッシュ間隔を3分に設定し、join_mv_incre という名前の高速マテリアライズドビューを作成します。
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 フィールドには、マテリアライズドビューの作成に使用される SQL ステートメントが含まれています。クエリ結果のフィールドの詳細については、「SHOW PROCESSLIST」をご参照ください。
SHOW PROCESSLIST ステートメントから情報が返されない場合、マテリアライズドビューの作成は完了です。これは、マテリアライズドビューのテーブルスキーマが作成され、初期データがマテリアライズドビューにロードされたことを示します。
マテリアライズドビューを作成するときにベーステーブルにクエリを書き込む
完全マテリアライズドビューのベーステーブルクエリ
完全マテリアライズドビューは、AnalyticDB for MySQL の内部テーブルと外部テーブル、既存のマテリアライズドビュー、およびビューに基づいて作成できます。ベーステーブルクエリに制限はありません。クエリ構文については、「SELECT」をご参照ください。
高速マテリアライズドビューのベーステーブルクエリ
高速マテリアライズドビューは、AnalyticDB for MySQL の内部テーブルと外部テーブルのみに基づいて作成できます。ベーステーブルクエリは、以下のルールに準拠する必要があります。
SELECT 列
GROUP BY 句で集計関数を指定する場合、SELECT 列には GROUP BY 句で参照されるすべての列を含める必要があります。
GROUP BY 句なしで集計関数を指定する場合、SELECT 列には定数列と集計列のみ、または集計列のみを含めることができます。
非集計クエリを指定する場合、SELECT 列にはベーステーブルのすべてのプライマリキー列を含める必要があります。
SELECT 句で参照される式ベースの列にはエイリアスを指定する必要があります。識別しやすいエイリアスを指定することをお勧めします。例:
SUM(price) AS total_price。
その他の制限
Elastic リソースを使用してマテリアライズドビューを作成またはリフレッシュする
Elastic リソースとは、ジョブリソースグループの計算資源を指します。AnalyticDB for MySQL クラスタでマテリアライズドビューを作成およびリフレッシュすると、クラスタの計算資源が使用されます。MV_PROPERTIES='{"mv_resource_group":"rg_name"}' パラメータを使用してリソースグループを指定しない場合、user_default という名前のデフォルトのインタラクティブリソースグループの予約済み計算資源がマテリアライズドビューの作成とリフレッシュに使用されます。
マテリアライズドビューの作成時にジョブリソースグループを指定すると、そのジョブリソースグループがマテリアライズドビューの作成とリフレッシュに使用されます。"mv_refresh_hints":{"elastic_job_max_acu":"value"} パラメータを使用して、マテリアライズドビューに使用可能なリソース量を指定できます。詳細については、「CREATE MATERIALIZED VIEW」トピックの「mv_properties」セクションをご参照ください。
マテリアライズドビューの作成またはリフレッシュ時のデフォルトのインタラクティブリソースグループとジョブリソースグループの違い:ジョブリソースグループを使用する場合、事前にリソースを購入する必要はありません。これにより、リソースの無駄を省き、コストを削減できます。ただし、デフォルトのインタラクティブリソースグループのリフレッシュパフォーマンスは、ジョブリソースグループよりも優れています。マテリアライズドビューをリフレッシュするたびに、ジョブリソースグループは計算資源をプロビジョニングするために数秒または数分かかります。
AnalyticDB for MySQL クラスタが以下の要件を満たしている場合、Elastic リソースを使用してマテリアライズドビューを作成およびリフレッシュできます。
クラスタは Enterprise Edition、Basic Edition、または Data Lakehouse Edition であること。
クラスタのマイナーバージョンが 3.1.9.3 以降であること。
my_job_rg という名前のジョブリソースグループの Elastic リソースを使用して、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 個のマテリアライズドビュー。
説明マテリアライズドビューの数がすでに上限に達している場合は、テクニカルサポートに連絡してマテリアライズドビューの最大数を増やすことができます。
完全マテリアライズドビューの制限
AnalyticDB for MySQL クラスタで予約リソースノードの数を調整する場合、非同期ジョブはサポートされていません。マテリアライズドビューの完全リフレッシュ操作は非同期ジョブです。そのため、予約リソースノードの数を調整する場合は、完全リフレッシュ操作を実行できません。ただし、高速リフレッシュ操作は影響を受けません。
高速マテリアライズドビューの制限
高速マテリアライズドビューのベーステーブルの制限:
XUANWU_V2 テーブルを高速マテリアライズドビューのベーステーブルとして使用することはできません。
理由は、XUANWU_V2 テーブルがバイナリロギング機能をサポートしていないためです。
V3.2.3.0 より前の AnalyticDB for MySQL クラスタでは、パーティションテーブルをベーステーブルとして使用して高速マテリアライズドビューを作成することはできません。
V3.2.3.1 より前の AnalyticDB for MySQL クラスタでは、高速マテリアライズドビューのベーステーブルで INSERT OVERWRITE または TRUNCATE ステートメントを実行することはできません。実行するとエラーが発生します。
マテリアライズドビュークエリで MAX()、MIN()、APPROX_DISTINCT()、または COUNT(DISTINCT) 関数を使用する場合、ベーステーブルで INSERT 操作のみを実行できます。DELETE、UPDATE、REPLACE、INSERT ON DUPLICATE KEY UPDATE など、データの削除につながる可能性のある操作は、ベーステーブルで実行できません。
高速マテリアライズドビューのリフレッシュトリガーメカニズムの制限:
高速マテリアライズドビューは、スケジュールされた間隔で自動的にリフレッシュすることのみが可能で、手動でリフレッシュすることはできません。高速リフレッシュのスケジュールされた間隔は 5 秒から 5 分です。
高速マテリアライズドビューのクエリの制限:
不定の値を生成する可能性のある式は指定できません。例:NOW() および RAND()。
ORDER BY 句は指定できません。
HAVING 句は指定できません。
ウィンドウ関数は指定できません。
UNION、EXCEPT、INTERSECT などの集合演算子は指定できません。
結合操作には INNER JOIN のみ指定できます。JOIN フィールドはベーステーブルの元のフィールドである必要があり、同じデータ型を使用し、インデックスの作成に使用される必要があります。最大 5 つのベーステーブルを結合できます。
より多くのベーステーブルを結合するには、テクニカルサポートに連絡してください。
指定できる集計関数は、COUNT()、SUM()、MAX()、MIN()、AVG()、APPROX_DISTINCT()、COUNT(DISTINCT) のみです。
AVG() 関数は DECIMAL 型をサポートしていません。
COUNT(DISTINCT) 関数は INTEGER 型のみをサポートしています。
FAQ
マテリアライズドビューに最新年のデータのみを保持するにはどうすればよいですか?
マテリアライズドビューを定義するときに、日付列をパーティションキーとして使用し、ライフサイクルを指定して最新年のデータのみを保持できます。
たとえば、sales テーブルには毎日新しい販売データが生成されます。sales テーブルに基づいてマテリアライズドビューを作成する場合、sale_date 列をパーティションキーとして使用し、ライフサイクルを 365 に設定できます。こうすることで、マテリアライズドビューには最新年のデータのみが保持されます。
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; ステートメントを実行して、demotable ベーステーブルのバイナリロギング機能を有効にします。
demotable ベーステーブルのバイナリロギング機能を有効にする際に XUANWU_V2 engine not support ALTER_BINLOG_ENABLE now エラーが発生した場合は、テーブルが XUANWU_V2 エンジンを使用していることを示します。XUANWU_V2 エンジンはバイナリロギング機能をサポートしていません。テーブルのエンジンは変更できません。XUANWU_V2 エンジンを無効にし、XUANWU エンジンを使用するテーブルを作成し、XUANWU_V2 テーブルから XUANWU テーブルにデータを移行してから、XUANWU テーブルに基づいて高速マテリアライズドビューを作成する必要があります。
XUANWU_V2 エンジンを無効にする方法:
Data Transmission Service (DTS)、zero-ETL、またはデータ同期を使用してベーステーブルが自動的に作成される場合は、クラスタレベルで XUANWU_V2 エンジンを無効にできます。XUANWU_V2 エンジンを無効にすると、新しいテーブルはすべて XUANWU エンジンを使用します。
クラスタレベルで XUANWU_V2 エンジンを無効にする:
SET adb_config RC_DDL_ENGINE_REWRITE_XUANWUV2=false;CREATE TABLE ステートメントを実行してベーステーブルを手動で作成し、高速マテリアライズドビューの作成に必要なベーステーブルの数が少ない場合は、関係する CREATE TABLE ステートメントで XUANWU_V2 エンジンを無効にできます。こうすることで、関係する CREATE TABLE ステートメントから XUANWU エンジンを使用するテーブルが作成されます。他の CREATE TABLE ステートメントは、引き続き XUANWU_V2 エンジンを使用するテーブルの作成に使用できます。
テーブルレベルで XUANWU_V2 エンジンを無効にする:
/*+ RC_DDL_ENGINE_REWRITE_XUANWUV2=false */CREATE TABLE ...
クエリ実行エラー: : PRIMARY KEY id must output to 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 です。ただし、sale_id は SELECT 句に含まれていません。
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 must be equal to base table 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 materialized view must define PRIMARY KEY
原因:このエラーは、以下の理由で発生する可能性があります。
高速マテリアライズドビューに正しいプライマリキーが指定されていません。
マテリアライズドビュークエリでベーステーブルのプライマリキーに関数が呼び出されています。
解決策:原因に基づいて最適な解決策を選択します。
マテリアライズドビューに正しいプライマリキーが指定されていない場合は、マテリアライズドビューの定義を変更して、プライマリキーが以下の要件を満たしていることを確認します。
GROUP BY 句で集計関数を指定する場合、プライマリキーは GROUP BY 句で参照される列である必要があります。たとえば、
GROUP BY a,bが指定されている場合、プライマリキーは列 a と b である必要があります。GROUP BY 句なしで集計関数を指定する場合、プライマリキーは定数である必要があります。
非集計クエリを指定する場合、プライマリキーはベーステーブルのプライマリキーと一致する必要があります。たとえば、ベーステーブルのプライマリキーが PRIMARY KEY(sale_id,sale_date) の場合、マテリアライズドビューのプライマリキーも PRIMARY KEY(sale_id,sale_date) である必要があります。
ベーステーブルのプライマリキーに関数が呼び出されている場合は、マテリアライズドビューのクエリを変更して関数を削除します。
クエリ実行エラー: : The join graph is not supported.
原因:高速マテリアライズドビューのクエリでベーステーブルの結合に使用される列のデータ型が異なります。例:sales INNER JOIN customer ON customer.id=sales.id。customer.id 列と sales.id 列のデータ型が異なる場合、このエラーが発生します。
解決策:ALTER TABLE tablename MODIFY COLUMN columnname newtype; ステートメントを実行して、列のデータ型を変更します。詳細については、「ALTER TABLE」トピックの「列のデータ型を変更する」セクションをご参照ください。
クエリ実行エラー: : Unable to use index join to refresh this fast MV.
原因:高速マテリアライズドビューのクエリでベーステーブルの結合に使用される列にインデックスが作成されていません。例:sales INNER JOIN customer ON customer.id=sales.id。customer.id 列または sales.id 列にインデックスが作成されていない場合、このエラーが発生します。
解決策:ALTER TABLE tablename ADD KEY idx_name(columnname); ステートメントを実行して、ベーステーブルの結合に使用される列にインデックスを作成します。詳細については、「ALTER TABLE」トピックの「インデックスを作成する」セクションをご参照ください。
クエリ実行エラー: : Query exceeded reserved memory limit
原因:単一ノードでのクエリのメモリ使用量が上限を超えています。
解決策:ほとんどの場合、メモリを大量に消費する SQL ステートメントには、Aggregation、TopN、Window、Join 演算子が含まれています。SQL 診断機能を使用して、メモリを大量に消費するステージと演算子を特定し、演算子に対して SQL 最適化を実行できます。詳細については、「クラスタパフォーマンスの最適化」トピックの「メモリメトリック」セクション、および「ステージとタスクの詳細を使用してクエリを分析する」をご参照ください。
参考資料
マテリアライズドビュー:マテリアライズドビューの概念、適用可能なシナリオ、および機能の更新について説明します。
CREATE MATERIALIZED VIEW:マテリアライズドビューの構文について説明します。
マテリアライズドビューのリフレッシュ:マテリアライズドビューのリフレッシュポリシーとトリガーメカニズム、およびマテリアライズドビューを手動でリフレッシュする方法について説明します。
マテリアライズドビューの管理:マテリアライズドビューの定義とリフレッシュレコードのクエリ、すべてのマテリアライズドビューのクエリ、およびマテリアライズドビューの削除方法について説明します。
マテリアライズドビューからのデータのクエリ:マテリアライズドビューからデータをクエリする方法について説明します。