All Products
Search
Document Center

PolarDB:Auto plan cache

Last Updated:Mar 28, 2026

Query optimization can take longer than execution itself for certain SQL patterns. When the same query runs repeatedly, re-optimizing each time adds unnecessary overhead. Auto Plan Cache stores execution plans and reuses them for matching queries, reducing optimization time and improving throughput.

Enable the feature by setting the loose_plan_cache_type parameter to AUTO, DEMAND, or ENFORCE based on your workload.

How it works

The query optimizer selects an execution plan based on statistics, join orders, and query transformations. For queries where optimization time is a significant fraction of total execution time, caching the plan eliminates repeated optimizer work for the same query pattern.

Auto Plan Cache intercepts queries that match configured thresholds and stores their execution plans. Subsequent queries matching the same parameterized pattern use the cached plan directly, skipping the optimization phase.

Cached plans are automatically invalidated when:

  • Statistics on referenced tables change

  • DDL operations are performed on referenced tables

Not all queries benefit from plan caching. For queries where the optimal plan depends heavily on parameter values—where different values lead to very different optimal plans—a fixed cached plan may degrade performance. Use AUTO mode to cache selectively, or DEMAND mode to control which queries are cached.

Supported versions

Auto Plan Cache requires one of the following:

  • PolarDB for MySQL 8.0.1, revision version 8.0.1.1.33 or later

  • PolarDB for MySQL 8.0.2, revision version 8.0.2.2.12 or later

Choose a caching mode

Set the mode using the loose_plan_cache_type parameter.

ModeWhen to use
AUTOCache execution plans automatically for queries that meet the time and ratio thresholds. Best for production workloads where you want selective caching without manual query management.
DEMANDCache only the queries you explicitly register using the dbms_sql.add_plan_cache stored procedure. Best when you know exactly which queries need caching.
ENFORCECache execution plans for all queries. Use only for testing or when all queries are known to benefit from caching.

OFF (default) disables plan caching entirely.

Configure parameters

Configure the following parameters on the Parameters page of the PolarDB console. For more information, see Configure cluster and node parameters.

ParameterDescriptionDefault
loose_plan_cache_typeThe caching mode: OFF, AUTO, DEMAND, or ENFORCE.OFF
loose_plan_cache_expire_timeHow long (in seconds) to retain a cached plan that has not been matched. Valid values: 0–4294967295.1800
loose_auto_plan_cache_pct_thresholdThe minimum ratio (as a percentage) of optimization time to total execution time required to cache a plan in AUTO mode. Valid values: 0–100.20
loose_auto_plan_cache_time_thresholdThe minimum total execution time (in microseconds) required to cache a plan in AUTO mode. Valid values: 0–18446744073709551615.400
loose_auto_plan_cache_count_thresholdThe minimum number of executions required before the cached plan takes effect in AUTO mode. Valid values: 0–18446744073709551615.512

AUTO mode cache conditions

A query's execution plan is cached only when both conditions are met:

  1. Total execution time >= loose_auto_plan_cache_time_threshold

  2. Optimization time / total execution time >= loose_auto_plan_cache_pct_threshold

The cached plan takes effect only after the query has been executed at least loose_auto_plan_cache_count_threshold times.

Use stored procedures

Add a query to the plan cache

CALL dbms_sql.add_plan_cache("schema_name", "query");

Use this procedure in DEMAND mode to explicitly register a query for caching. Replace schema_name with the target schema and query with the SQL statement to cache.

Example:

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

After this call, any query matching the template SELECT * FROM t_for_plan WHERE c1 > ? AND c1 < ? uses the cached execution plan.

View tables referenced in the plan cache

CALL dbms_sql.display_plan_cache_table()\G

Sample output:

*************************** 1. row ***************************
 SCHEMA_NAME: test
  TABLE_NAME: t_for_plan
   REF_COUNT: 1
     VERSION: 0
VERSION_TIME: 2023-03-10 17:21:35.605264
FieldDescription
SCHEMA_NAMEThe schema where the referenced table resides
TABLE_NAMEThe name of the referenced table
REF_COUNTThe number of cached plans that reference this table
VERSIONThe current version of the table in the plan cache
VERSION_TIMEThe time the current version was recorded

Delete a cached execution plan

CALL dbms_sql.delete_sharing_by_rowid(row_id);

row_id is the Id value from the mysql.sql_sharing table.

To find the row ID and delete the plan:

  1. Query the plan cache for the target statement:

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

    Sample output:

    *************************** 1. row ***************************
             Id: 1
    Schema_name: test
           Type: PLAN_CACHE
    Digest_text: SELECT * FROM `t_for_plan` WHERE `c1` > ? AND `c1` < ?
  2. Delete the plan using the Id value:

    CALL dbms_sql.delete_sharing_by_rowid(1);

Query the plan cache

Execution plans are stored in the SQL Sharing module. Query the INFORMATION_SCHEMA.SQL_SHARING table to inspect cached plans:

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

The EXTRA field contains a PLAN_CACHE_INFO object showing the referenced tables, their versions, and the number of cache hits.

End-to-end example using DEMAND mode

  1. Create a test table:

    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. Set the caching mode to DEMAND. Use either method:

    • In the PolarDB console, go to the Parameters page, set loose_plan_cache_type to DEMAND, then reconnect to the database.

    • In the current session:

      SET plan_cache_type = demand;
  3. Register the query for caching:

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

    SELECT * FROM t_for_plan WHERE c1 > 1 AND c1 < 10;
  5. Verify the cached plan:

    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

    Sample output:

    *************************** 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}}

    The PLAN_CACHE_INFO in the EXTRA field shows the referenced table, its version, and the number of cache hits.

Performance data

A stress test on an 8-core, 32 GB cluster with 25 tables of 4 million rows each. The test query was SELECT id FROM sbtestN WHERE k IN(...) with an IN list of 20 values, run under both the Prepared Statement (PS) protocol and the non-PS protocol.

  • The following figure shows the performance test results for the PS protocol.PS协议下的查询性能

  • The following figure shows the performance test results for the non-PS protocol.非PS协议下的查询性能

Auto Plan Cache improved throughput by more than 50% for both protocols compared to the baseline (OFF mode).

These results are from a workload where optimization time is a significant fraction of total query time. Workloads dominated by execution time rather than optimization time will see smaller gains. If your queries are short-running or their optimal plans vary significantly by parameter value, measure the impact before enabling the feature in production.