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

PolarDB:自動プランキャッシュ

最終更新日:Jun 14, 2025

SQL 文の実行計画をキャッシュしてクエリ最適化時間を短縮し、SQL 文のクエリパフォーマンスを向上させるために、PolarDB for MySQL が提供する自動プランキャッシュ機能を使用できます。このトピックでは、自動プランキャッシュ機能について説明します。

背景情報

実行計画の選択は、統計、結合順序、クエリ変換など、多くの要因によって異なります。最適化時間は、クエリ文によって異なります。一部の SQL 文の最適化時間は、全体の実行時間と比較して非常に長くなる場合があります。このような SQL 文が複数回実行されると、最適化時間が長いため、システム負荷が増加します。 SQL 文の実行計画をキャッシュして再利用することで、SQL 文の実行時の最適化時間を短縮できます。これにより、クエリのパフォーマンスが向上し、データベースの負荷が軽減され、スループットが向上します。

対照的に、一部のクエリ文のクエリ最適化時間は非常に短いです。実行時間は、実行計画に大きく依存します。SQL 文のパラメーター値も、最適な実行計画を決定します。シナリオによっては、MySQL はパラメーター値に基づいてエンジンから取得した実際のデータを最適化します。

上記のクエリ文で固定実行計画を使用した場合、クエリの応答時間と負荷のオーバーヘッドは大幅に最適化されません。クエリのパフォーマンスが低下することさえあります。

最適化時間が非常に長い SQL 文のクエリパフォーマンスを向上させ、システム負荷を軽減し、SQL 文の実行時に固定実行計画によって発生するクエリパフォーマンスの低下を回避するために、PolarDB for MySQL は自動プランキャッシュ機能を起動します。自動プランキャッシュ機能は、AUTO、DEMAND、ENFORCE の 3 つのモードをサポートしています。loose_plan_cache_type パラメーターを設定してモードを選択し、プランキャッシュに SQL 文の実行計画をキャッシュして最適化時間を短縮し、クエリパフォーマンスを向上させることができます。プランキャッシュにキャッシュされた実行計画で参照されるテーブルの統計が変更された場合、またはプランキャッシュにキャッシュされた実行計画で参照されるテーブルで DDL 操作が実行された場合、キャッシュされた実行計画は自動的に無効になります。

前提条件

PolarDB クラスタは、次のいずれかのバージョンを使用しています。

  • PolarDB for MySQL 8.0.1 のクラスタで、リビジョンバージョンが 8.0.1.1.33 以降。

  • PolarDB for MySQL 8.0.2 のクラスタで、リビジョンバージョンが 8.0.2.2.12 以降。

パラメーター

PolarDBコンソール で、次のパラメーターを設定できます。詳細については、「クラスタとノードのパラメーターを設定する」をご参照ください。

パラメーター

説明

loose_plan_cache_type

自動プランキャッシュモード。有効な値:

  • OFF(デフォルト):自動プランキャッシュ機能を無効にします。

  • AUTO:キャッシュ条件を満たす SQL 文の実行計画を自動的にキャッシュします。

    説明

    キャッシュ条件:

    SQL 文の全体の実行時間が loose_auto_plan_cache_time_threshold 値以上であり、SQL 文の最適化時間の全体の実行時間に対する比率が loose_auto_plan_cache_pct_threshold 値以上である場合、SQL 文の実行計画はキャッシュされます。

  • DEMAND:指定された SQL 文の実行計画をキャッシュします。

  • ENFORCE:すべての SQL 文の実行計画を強制的にキャッシュします。

loose_plan_cache_expire_time

実行計画がヒットしない場合にプランキャッシュが再利用されるまでの期間。単位:秒。

有効な値:0 ~ 4294967295。デフォルト値:1800。

loose_auto_plan_cache_pct_threshold

SQL 文の最適化時間の全体の実行時間に対する指定比率。

有効な値:0 ~ 100。デフォルト値:20。

loose_auto_plan_cache_time_threshold

SQL 文の指定された全体の実行時間。単位:マイクロ秒。

有効な値:0 ~ 18446744073709551615。デフォルト値:400。

loose_auto_plan_cache_count_threshold

loose_plan_cache_type パラメーターが AUTO に設定されている場合に、キャッシュ条件を満たす SQL 文の実行計画をキャッシュするために許可される操作の数。

有効な値:0 ~ 18446744073709551615。デフォルト値:512。

説明

キャッシュされた実行計画は、実行計画をキャッシュするために許可される操作の数が loose_auto_plan_cache_count_threshold 値以上の場合にのみ有効になります。

ストアドプロシージャ

  • dbms_sql.add_plan_cache(schema, query):指定された SQL 文の実行計画をプランキャッシュにキャッシュします。

    loose_plan_cache_type パラメーターが DEMAND に設定されている場合、この組み込みストアドプロシージャを使用して、指定された SQL 文の実行計画をプランキャッシュにキャッシュできます。例:

    CALL dbms_sql.add_plan_cache("test", "SELECT * FROM t_for_plan WHERE c1 > 1 AND c1 < 10");

    上記の文が実行された後、実行された SQL 文が SELECT * FROM t_for_plan WHERE c1 > ? AND c1 < ? テンプレートと一致する場合、SQL 文の実行計画はプランキャッシュにキャッシュされます。

  • dbms_sql.display_plan_cache_table():プランキャッシュで参照されるテーブルに関する情報を表示します。例:

    CALL dbms_sql.display_plan_cache_table()\G

    結果例:

    *************************** 1. row ***************************
     SCHEMA_NAME: test
      TABLE_NAME: t_for_plan
       REF_COUNT: 1
         VERSION: 0
    VERSION_TIME: 2023-03-10 17:21:35.605264

    ストアドプロシージャのパラメーター:

    • SCHEMA_NAME:参照されるテーブルが存在するスキーマの名前。

    • TABLE_NAME:参照されるテーブルの名前。

    • REF_COUNT:プランキャッシュ内のテーブルの参照数。

    • VERSION:プランキャッシュ内の参照されるテーブルのバージョン。

    • VERSION_TIME:現在のバージョンのテーブルが参照された時刻。

  • dbms_sql.delete_sharing_by_rowid(row_id):指定された SQL 文の実行計画を削除します。

    row_idmysql.sql_sharing テーブルに格納されている実行計画の行 ID 値。

    1. 次の SQL 文を実行して、プランキャッシュにキャッシュされている実行計画をクエリします。

      SELECT Id, Schema_name, Type, Digest_text FROM mysql.sql_sharing WHERE Type = 'PLAN_CACHE'\G

      結果例:

      *************************** 1. row ***************************
               Id: 1
      Schema_name: test
             Type: PLAN_CACHE
      Digest_text: SELECT * FROM `t_for_plan` WHERE `c1` > ? AND `c1` < ?

      結果は、row_id 値が 1 であることを示しています。

    2. 前のクエリで取得した実行計画を削除します。

      CALL dbms_sql.delete_sharing_by_rowid(1);

プランキャッシュのクエリ情報

INFORMATION_SCHEMA.SQL_SHARING テーブルから次の SQL 文を実行して、プランキャッシュの情報をクエリできます。

SELECT TYPE, REF_BY, SQL_ID, SCHEMA_NAME, DIGEST_TEXT, PLAN_ID, PLAN, PLAN_EXTRA, EXTRA FROM INFORMATION_SCHEMA.SQL_SHARING WHERE json_contains(REF_BY, '"PLAN_CACHE"') or json_contains(REF_BY, '"PLAN_CACHE(DEMAND)"')\G

  1. データを準備します。

    CREATE TABLE t_for_plan AS WITH RECURSIVE t(c1, c2, c3) AS (SELECT 1, 1, 1 UNION ALL SELECT c1+1, c1 % 50, c1 %200 FROM t WHERE c1 < 1000) SELECT c1, c2, c3 FROM t;
    CREATE INDEX i_c1_c2 on t_for_plan(c1, c2);
  2. 自動プランキャッシュモードを DEMAND に設定します。

    次のいずれかの方法を使用して、自動プランキャッシュモードを設定できます。

    • PolarDBコンソール[パラメーター] ページで、loose_plan_cache_type パラメーターを DEMAND に設定します。データベースから切断し、再接続します。

    • 現在のデータベース接続を維持し、次の文を実行して、現在のセッションの plan_cache_type パラメーターを DEMAND に設定します。

      SET plan_cache_type=demand;
  3. 次の文を実行して、指定された SQL 文の実行計画をプランキャッシュにキャッシュします。

    CALL dbms_sql.add_plan_cache("test", "SELECT * FROM t_for_plan WHERE c1 > 1 AND c1 < 10");
  4. クエリ文を実行します。

    SELECT * FROM t_for_plan WHERE c1 > 1 AND c1 < 10;
  5. プランキャッシュの情報をクエリします。

    SELECT TYPE, REF_BY, SQL_ID, SCHEMA_NAME, DIGEST_TEXT, PLAN_ID, PLAN, PLAN_EXTRA, EXTRA FROM INFORMATION_SCHEMA.SQL_SHARING WHERE json_contains(REF_BY, '"PLAN_CACHE"') or json_contains(REF_BY, '"PLAN_CACHE(DEMAND)"')\G

    結果例:

    *************************** 1. row ***************************
           TYPE: SQL
         REF_BY: ["PLAN_CACHE(DEMAND)"]
         SQL_ID: 9jrvksr3wjux6
    SCHEMA_NAME: test
    DIGEST_TEXT: SELECT * FROM `t_for_plan` WHERE `c1` > ? AND `c1` < ?
        PLAN_ID: NULL
           PLAN: NULL
     PLAN_EXTRA: NULL
          EXTRA: {"TRACE_ROW_ID":1}
    *************************** 2. row ***************************
           TYPE: PLAN
         REF_BY: ["PLAN_CACHE"]
         SQL_ID: 9jrvksr3wjux6
    SCHEMA_NAME: test
    DIGEST_TEXT: NULL
        PLAN_ID: 08xftakma6pm6
           PLAN: /*+ INDEX(`t_for_plan`@`select#1` `i_c1_c2`) */
     PLAN_EXTRA: {"access_type":["`t_for_plan`:range"]}
          EXTRA: {"PLAN_CACHE_INFO":{"tables":[`test`.`t_for_plan`], "versions":[0], "hits": 0}}

    EXTRA フィールドの PLAN_CACHE_INFO 項目には、参照されるテーブル、参照されるテーブルのバージョン、および実行計画のヒット数が表示されます。

パフォーマンスデータ

8 コアと 32 GB のメモリを使用するクラスタに対してストレステストを実行します。データベースには 25 個のテーブルが作成されます。各テーブルには 400 万行のデータが格納されます。テストで使用される SQL 文は、SELECT id FROM sbtestN WHERE k IN(...) です。IN LIST の長さは 20 です。 loose_plan_cache_type パラメーターが OFFAUTO、および ENFORCE に設定されている場合のパフォーマンスを、PS プロトコルと非 PS プロトコルの両方でテストします。テスト結果:

  • 次の図は、PS プロトコルのパフォーマンステスト結果を示しています。PS协议下的查询性能

  • 次の図は、非 PS プロトコルのパフォーマンステスト結果を示しています。非PS协议下的查询性能

テスト結果は、自動プランキャッシュ機能により、PS プロトコルと非 PS プロトコルの両方でパフォーマンスが 50% 以上向上することを示しています。