すべてのプロダクト
Search
ドキュメントセンター

AnalyticDB:マテリアライズド・ビューのクエリ書き換え

最終更新日:Dec 02, 2024

AnalyticDB for MySQLを使用すると、具体化されたビューをクエリでき、クエリの書き換え機能を提供します。 クエリ書き換え機能は、マテリアライズドビューを使用するようにクエリを自動的に書き換え、クエリのパフォーマンスを向上させます。 このトピックでは、マテリアライズドビューのクエリ書き換え機能の使用方法について説明します。

前提条件

  • V3.1.4.0以降のAnalyticDB for MySQLクラスターが作成されます。

    説明
    • AnalyticDB for MySQLのマイナーバージョンを照会するには

      Data Lakehouse Editionクラスターで、SELECT adb_version(); 文を実行します。 クラスターのマイナーバージョンを更新するには、テクニカルサポートにお問い合わせください。

    • AnalyticDB For MySQL Data Warehouse Editionクラスターのマイナーバージョンを表示および更新する方法については、「クラスターのマイナーバージョンの更新」をご参照ください。

  • マテリアライズド・ビューを使用するには、次の権限が必要です。

    • ビューを作成するには、データベースまたはテーブルに対するcreate権限が必要です。

    • マテリアライズドビューを更新するには、データベースまたはテーブルに対するINSERT権限が必要です。

    • 関連するテーブル列またはマテリアライズドビューに含まれるすべてのテーブルに対するSELECT権限が必要です。

    • 作成したマテリアライズドビューの自動更新を構成する場合は、オンプレミスサーバー (127.0.0.1) またはIPアドレス ('%') を使用してビューを更新する権限が必要です。

概要

マテリアライズドビューを直接クエリするか、マテリアライズドビューのクエリ書き換え機能を有効にすることができます。 クエリ書き換え機能を有効にすると、マテリアライズド・ビューを参照しないクエリをマテリアライズド・ビューを使用するように書き換えることができます。 この場合、具体化されたビューはキャッシュとして使用され、SQL文を変更する必要なくクエリを高速化します。 AnalyticDB for MySQLを使用すると、マテリアライズドビューと同じ構造を持つクエリを書き換え、書き換えルールを使用してマテリアライズドビューと同等のクエリを書き換えることができます。

  • クエリの書き換え方法

    AnalyticDB for MySQLは、クエリステートメントの構造がマテリアライズドビューの構造と同じかどうかをチェックし、チェック結果に基づいて適切なクエリの書き換え方法を選択します。 AnalyticDB for MySQLは、次のクエリ書き換え方法をサポートしています。

    • 完全一致の書き換え

      クエリステートメントの構造がマテリアライズドビューの構造とまったく同じである場合、AnalyticDB for MySQLはマテリアライズドビューを使用するようにクエリステートメントを書き換えます。 これは、制限の少ないシンプルで基本的な書き換え方法です。 制限については、このトピックの「制限」セクションを参照してください。

    • 高度なクエリの書き換え

      クエリステートメントの構造がマテリアライズドビューの構造と異なる場合、AnalyticDB for MySQLは書き換えルールを使用して、マテリアライズドビューにクエリに必要なデータが含まれているかどうかを確認します。 AnalyticDB for MySQLは、クエリの各部分とサブクエリの書き換えを試みます。 クエリの異なる部分は、異なる具体化ビューを使用し得る。 サポートされている書き換え範囲と高度なクエリ書き換え方法の制限については、このトピックの「書き換え範囲」および「制限」を参照してください。

  • クエリ書き換えレベル

    AnalyticDB for MySQLは、STALE_TOLERATEDレベルでのみクエリの書き換えをサポートします。 マテリアライズドビューにベーステーブルの最新データを反映しない古いデータが含まれている場合でも、クエリを書き直してマテリアライズドビューを使用してクエリのパフォーマンスを向上させることができます。 STALE_TOLERATEDレベルは最大の書き換え機能を提供しますが、不正確なクエリ結果を生成する可能性があります。 クエリの書き換え機能を使用する前に、マテリアライズドビューを更新して最新の結果を取得することをお勧めします。 詳細については、「マテリアライズドビューのフル更新の設定」をご参照ください。

クエリの書き換え機能を使用する

クエリの書き換え機能の有効化

AnalyticDB for MySQLでは、次のいずれかの方法を使用して、クエリの書き換え機能を有効にできます。

  • マテリアライズドビューを作成するときは、ENABLE QUERY REWRITE句を指定します。 詳細については、「マテリアライズド・ビューの作成」トピックの「パラメーター」セクションをご参照ください。

  • マテリアライズド・ビューを作成したら、ALTER materialized view <mv_name> ENABLE QUERY REWRITE; ステートメントを実行します。 詳細については、「マテリアライズドビューの管理」をご参照ください。

クエリの書き換え機能を無効にする

AnalyticDB for MySQLでは、次のいずれかの方法を使用して、クエリの書き換え機能を無効にできます。

  • ALTER MATERIALIZED VIEW <mv_name> DISABLE QUERY REWRITE; ステートメントを実行します。 詳細については、「マテリアライズドビューの管理」をご参照ください。

  • SQL文の前にヒントを追加して、クエリがクエリの書き換え機能を使用しないようにします。 構文:

  • /*+MV_QUERY_REWRITE_ENABLED=false*/
    SELECT ...

例:

  1. マテリアライズドビューを作成するときに、クエリの書き換え機能を有効にします。

    CREATE MATERIALIZED VIEW adb_mv
    REFRESH START WITH now() + interval 1 day
    ENABLE QUERY REWRITE
    AS
    SELECT course_id,course_name,max(course_grade) AS max_grade FROM tb_courses;
  2. クエリを実行します。

    SELECT course_id,course_name,max(course_grade) AS max_grade FROM tb_courses;
  3. EXPLAINステートメントを実行して、クエリの書き換え機能が有効かどうかを確認します。

    EXPLAIN SELECT course_id,course_name,max(course_grade) AS max_grade FROM tb_courses;

    サンプル結果:

    +---------------+
    | Plan Summary |
    +---------------+
     1- Output[ Query plan ] {Est rowCount: 1.0}
     2    -> Exchange[GATHER] {Est rowCount: 1.0}
     3        - TableScan {table: adb_mv, Est rowCount: 1.0}

    上記の実行計画では、tb_coursesテーブルのデータではなく、adb_mvマテリアライズドビューに格納されているデータがクエリで使用されることを示しています。

制限事項

  • 具体化されたビューに書き換えできないコンテンツが含まれている場合、クエリの書き換え機能は有効になりません。

    AnalyticDB for MySQLは、完全一致書き換え方式と高度なクエリ書き換え方式のクエリ書き換え機能に異なる制限を課します。

    • マテリアライズド・ビューに次のコンテンツが含まれている場合、完全一致の書き換え方法は有効になりません。

      • NOWCURRENT_TIMESTAMPRANDOMなどの非決定性関数

      • ユーザー定義関数 (UDF)

    • マテリアライズドビューに次のコンテンツが含まれている場合、高度なクエリの書き換え方法は有効になりません。

      • ORDER BY、LIMIT、またはOFFSET句

      • UNIONまたはUNION ALL句

      • GROUP BY句のGROUPING SETS、CUBE、またはROLLUP

      • Window 関数

      • FULL OUTER JOIN句

      • システムテーブル

      • 相関サブクエリ

      • NOWCURRENT_TIMESTAMPRANDOMなどの非決定性関数

      • UDF

      • HAVING 句

      • SELF JOIN句

  • クエリが次のいずれかのステートメントに含まれている場合、クエリの書き換え機能は有効になりません。

    • SELECTとしてテーブルを作成する

    • セレクトに挿入

    • 上書き選択を挿入する

    • 選択場所への置き換え

    • 削除または更新

  • その他のシナリオ

    単一テーブルのクエリ文にフィルター条件や集計関数がない場合、クエリの書き換え機能は有効になりません。

範囲の書き換え

以下の例では、同じ表を使用する。 次のステートメントを実行してテーブルを作成します。

CREATE TABLE part (
  partkey INTEGER NOT NULL,
  name VARCHAR(55) NOT NULL,
  type VARCHAR(25) NOT NULL
);

CREATE TABLE lineitem (
  orderkey BIGINT,
  partkey BIGINT NOT NULL,
  suppkey BIGINT NOT NULL,
  extendedprice DOUBLE NOT NULL,
  discount DOUBLE NOT NULL,
  returnflag CHAR(1) NOT NULL,
  linestatus CHAR(1) NOT NULL,
  shipdate DATE NOT NULL,
  shipmode VARCHAR(25) NOT NULL,
  commitdate DATE NOT NULL,
  receiptdate DATE NOT NULL
);
  
CREATE TABLE orders (
  orderkey BIGINT PRIMARY KEY,
  custkey BIGINT NOT NULL,
  orderstatus VARCHAR(1) NOT NULL,
  totalprice DOUBLE NOT NULL,
  orderdate DATE NOT NULL
);
CREATE TABLE partsupp (
  partkey INTEGER NOT NULL PRIMARY KEY,
  suppkey INTEGER NOT NULL,
  availqty INTEGER NOT NULL,
  supplycost DECIMAL(15,2) NOT NULL
);

完全一致の書き換え

AnalyticDB for MySQLは、クエリステートメントの構造がマテリアライズドビューの構造と同じであるかどうかを確認します。 クエリステートメントとマテリアライズドビューの構造がまったく同じ場合、AnalyticDB for MySQLはマテリアライズドビューを使用するようにクエリステートメントを書き換えます。

  • クエリ文を実行します。

    SELECT
      l.returnflag,
      l.linestatus, 
      SUM(l.extendedprice * (1 - l.discount)), 
      COUNT(*) AS count_order
    FROM lineitem AS l 
    GROUP BY l.returnflag, l.linestatus;
  • マテリアライズドビューを作成します。

    CREATE MATERIALIZED VIEW mv0
    REFRESH NEXT now() + interval 1 day
    ENABLE QUERY REWRITE
    AS
    SELECT
      l.returnflag,
      l.linestatus,
      SUM (l.extendedprice * (1 - l.discount)) AS sum_disc_price,
      count(*) AS count_order
    FROM lineitem AS l
    GROUP BY l.returnflag, l.linestatus;
  • マテリアライズド・ビューのクエリ書き換え機能を有効にした後にクエリ文を実行すると、クエリ文は次のように書き換えられます。

    SELECT returnflag, linestatus, sum_disc_price, count_order
    FROM mv0;

高度なクエリの書き換え

クエリステートメントの構造がマテリアライズドビューの構造と異なる場合、AnalyticDB for MySQLは書き換えルールを使用して、FILTERJOINAGGREGATION、およびGROUP BY式を順番にチェックします。 次に、AnalyticDB for MySQLは、マテリアライズドビューを使用してクエリまたはクエリの一部に回答することにより、同等のクエリ式を構築しようとします。

高度なクエリ書き換え方法は、次の書き換えルールをサポートします。

  • フィルター

    クエリステートメントの述語がマテリアライズドビューの述語と異なる場合、AnalyticDB for MySQLはFILTERルールを使用して補償式を構築します。 クエリステートメントに含まれる式がマテリアライズドビューに存在しない場合、AnalyticDB for MySQLはマテリアライズドビューで式の計算を試みます。 例:

    • クエリ文を実行します。

      SELECT
          l.shipmode,
          l.extendedprice * (1 - l.discount) AS disc_price
      FROM
          orders AS o,
          lineitem AS l
      WHERE o.orderkey = l.orderkey
          AND l.shipmode in ('REG AIR', 'TRUCK')
          AND l.commitdate < l.receiptdate
          AND l.shipdate < l.commitdate;
    • マテリアライズドビューを作成します。

      CREATE MATERIALIZED VIEW mv1
      REFRESH NEXT now() + interval 1 day
      ENABLE QUERY REWRITE
      AS 
      SELECT
        l.shipmode,
        l.extendedprice,
        l.discount
      FROM
        orders AS o,
        lineitem AS l
      WHERE o.orderkey = l.orderkey
        AND l.commitdate < l.receiptdate
        AND l.shipdate < l.commitdate;
    • マテリアライズド・ビューのクエリ書き換え機能を有効にした後にクエリ文を実行すると、クエリ文は次のように書き換えられます。

      SELECT
          shipmode,
          extendedprice * (1 - discount) AS disc_price,
          discount
      FROM mv1
      WHERE shipmode in ('REG AIR', 'TRUCK');
  • 参加

    AnalyticDB for MySQLは、クエリとマテリアライズドビューの内部結合、外部結合、左結合、右結合をサポートします。 クエリとマテリアライズドビューに異なる結合関係が含まれている場合、AnalyticDB for MySQLは、joinルールを使用して、マテリアライズドビューに基づいてクエリに必要な結合関係を計算しようとします。 たとえば、AnalyticDB for MySQLは、マテリアライズドビューのデータの行をフィルタリングします。 このように、外部結合を含むマテリアライズドビューを使用して、内部結合関係を含むクエリを計算できます。 例:

    • クエリ文を実行します。

      SELECT
        p.type,
        p.partkey,
        ps.suppkey
      FROM
        part AS p,
        partsupp AS ps
      WHERE p.partkey = ps.partkey
        AND p.type NOT LIKE  'MEDIUM POLISHED%';
    • マテリアライズドビューを作成します。

      CREATE MATERIALIZED VIEW mv2
      REFRESH NEXT now() + INTERVAL 1 day
      ENABLE QUERY REWRITE
      AS 
      SELECT 
        p.type,
        p.partkey,
        ps.suppkey
      FROM
        partsupp AS ps 
        INNER JOIN part AS p ON p.partkey = ps.partkey
      WHERE p.type NOT LIKE 'MEDIUM POLISHED%';
    • マテリアライズド・ビューのクエリ書き換え機能を有効にした後にクエリ文を実行すると、クエリ文は次のように書き換えられます。

      SELECT type, partkey, suppkey
      FROM mv2;
  • AGGREGATION

    クエリまたはマテリアライズドビューで異なるGROUP BY句または集計関数を使用する場合、AnalyticDB for MySQLAGGREGATIONルールを使用してマテリアライズドビューから同じ集計関数を作成します。 例:

    • クエリ文を実行します。

      SELECT
        l.returnflag,
        l.linestatus,
        SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price
      FROM lineitem AS l
      GROUP BY l.returnflag, l.linestatus;
    • マテリアライズドビューを作成します。

      CREATE MATERIALIZED VIEW mv3
      REFRESH NEXT now() + INTERVAL 1 day
      ENABLE QUERY REWRITE
      AS
      SELECT
          l.returnflag,
          l.linestatus, 
          SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price, 
          COUNT(*) AS count_order
      FROM lineitem AS l 
      GROUP BY l.returnflag, l.linestatus;
    • マテリアライズド・ビューのクエリ書き換え機能を有効にした後にクエリ文を実行すると、クエリ文は次のように書き換えられます。

      SELECT returnflag, linestatus, sum_disc_price, count_order
      FROM mv3;
  • AGGREGATION ROLLUP

    クエリとマテリアライズドビューが異なるGROUP BYフィールドを使用する場合、AnalyticDB for MySQLROLLUPルールを使用してマテリアライズドビューをロールアップしようとします。 例:

    • クエリ文を実行します。

      SELECT
        l.returnflag,
        SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price,
        COUNT(*) AS count_order
      FROM lineitem AS l
      WHERE l.returnflag = 'R'
      GROUP BY  l.returnflag;
    • マテリアライズドビューを作成します。

      CREATE MATERIALIZED VIEW mv4
      REFRESH NEXT now() + INTERVAL 1 day
      ENABLE QUERY REWRITE
      AS
      SELECT
          l.returnflag,
          l.linestatus, 
          SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price, 
          COUNT(*) AS count_order
      FROM lineitem AS l 
      GROUP BY l.returnflag, l.linestatus;
    • マテリアライズド・ビューのクエリ書き換え機能を有効にした後にクエリ文を実行すると、クエリ文は次のように書き換えられます。

      SELECT 
        returnflag, 
        linestatus,
        sum_disc_price, 
        count_order
      FROM mv4
      WHERE returnflag = 'R'
      GROUP BY returnflag;
  • サブクエスト

    クエリとマテリアライズドビューに異なるサブクエリがある場合、AnalyticDB for MySQLsubqueriesルールを使用してクエリの書き換えを試みます。 例:

    • クエリ文を実行します。

      SELECT
        p.type,
        p.partkey,
        ps.suppkey
      FROM
        part AS p,
        (SELECT * FROM partsupp WHERE suppkey > 10) ps
      WHERE p.partkey = ps.partkey;
    • マテリアライズドビューを作成します。

      CREATE MATERIALIZED VIEW mv5
      REFRESH NEXT now() + INTERVAL 1 day
      ENABLE QUERY REWRITE
      AS 
      SELECT 
        p.type,
        p.partkey,
        ps.suppkey
      FROM
        part AS p,
        partsupp AS ps
      WHERE p.partkey = ps.partkey;
    • マテリアライズド・ビューのクエリ書き換え機能を有効にした後にクエリ文を実行すると、クエリ文は次のように書き換えられます。

      SELECT 
        type,
        partkey,
        suppkey
      FROM mv5
      WHERE suppkey > 10;
  • クエリパーティー

    クエリに関連するテーブルがマテリアライズドビューに存在しない場合、AnalyticDB for MySQLは、query PARTIALルールを使用して、不足しているテーブルをマテリアライズドビューに結合しようとします。 例:

    • クエリ文を実行します。

      SELECT 
        p.type,
        p.partkey,
        ps.suppkey
      FROM
        part AS p,
        partsupp AS ps
      WHERE p.partkey = ps.partkey
          AND p.type NOT LIKE 'MEDIUM POLISHED%';
    • マテリアライズドビューを作成します。

      CREATE MATERIALIZED VIEW mv6
      REFRESH NEXT now() + INTERVAL 1 day
      ENABLE QUERY REWRITE
      AS
      SELECT
        p.type,
        p.partkey
      FROM
        part AS p
      WHERE p.type NOT LIKE  'MEDIUM POLISHED%';
    • マテリアライズド・ビューのクエリ書き換え機能を有効にした後にクエリ文を実行すると、クエリ文は次のように書き換えられます。

      SELECT
        mv6.type,
        mv6.partkey,
        ps.suppkey
      FROM 
        mv6,
        partsupp AS ps
      WHERE mv6.partkey = ps.partkey;
  • ユニオン

    マテリアライズドビューにクエリに必要な特定のデータのみが含まれている場合、AnalyticDB for MySQLは、UNIONルールを使用して、マテリアライズドビューの既存のデータから特定のクエリ結果を取得し、ベーステーブルから残りのクエリ結果を取得します。

    • クエリ文を実行します。

      SELECT
        l.linestatus,
        COUNT(*) AS count_order
      FROM lineitem AS l
      WHERE l.shipdate >= DATE '1998-01-01'
      GROUP BY l.linestatus;
    • マテリアライズドビューを作成します。

      CREATE MATERIALIZED VIEW mv7
      REFRESH NEXT now() + interval 1 day
      ENABLE QUERY REWRITE
      AS
      SELECT
        l.linestatus,
        COUNT(*) AS count_order
      FROM lineitem AS l 
      WHERE l.shipdate >= DATE '2000-01-01'
      GROUP BY l.linestatus;
    • マテリアライズド・ビューのクエリ書き換え機能を有効にした後にクエリ文を実行すると、クエリ文は次のように書き換えられます。

      SELECT 
        linestatus,
        count_order
      FROM (
          SELECT linestatus, count_order
        FROM mv7
      UNION ALL
          SELECT 
            l.linestatus,
            COUNT(*) AS count_order
          FROM lineitem AS l 
          WHERE l.shipdate >= DATE '1998-01-01' AND l.shipdate < DATE '1998-01-01'
          GROUP BY l.linestatus) 
      GROUP BY linestatus;

よくある質問

Q: マテリアライズドビューを作成した後にクエリの書き換え機能が有効にならないのはなぜですか。

A: クエリの書き換え機能が有効にならない場合は、次の操作を実行します。

  • マテリアライズドビューのクエリ書き換え機能が有効になっているかどうかを確認します。 詳細については、このトピックの「クエリの書き換え機能の使用」を参照してください。

  • マテリアライズドビューに制限があるかどうかを確認します。 詳細については、このトピックの「制限」セクションを参照してください。

  • マテリアライズドビューに対するSELECT権限があるかどうかを確認します。 GRANTステートメントを実行して、クエリの実行に使用するデータベースアカウントに必要な権限を付与できます。 詳細については、マテリアライズドビューからのクエリデータの「必要なアクセス許可」セクションをご参照ください。