PolarDB for MySQLが提供するキャッシュの自動計画機能を使用して、SQL文の実行計画をキャッシュし、クエリの最適化時間を短縮し、SQL文のクエリパフォーマンスを向上させることができます。 このトピックでは、自動プランキャッシュ機能について説明します。
背景情報
実行計画の選択は、統計、結合順序、クエリ変換などの多くの要因に依存します。 最適化時間は、クエリ文によって異なります。 一部のSQLステートメントの最適化時間は、全体の実行時間と比較して非常に長い場合があります。 このようなSQL文を複数回実行すると、最適化に時間がかかるため、システム負荷が増大する。 SQL文の実行計画をキャッシュして再利用することで、SQL文の実行時の最適化時間を短縮できます。 これにより、クエリのパフォーマンスが向上し、データベースの負荷が軽減され、スループットが向上します。
対照的に、いくつかのクエリステートメントは、非常に短いクエリ最適化時間を有する。 それらの実行時間は実行計画に大きく依存します。 SQL文のパラメーター値も最適な実行計画を決定します。 一部のシナリオでは、MySQLはパラメーター値に基づいてエンジンから取得した実際のデータを最適化します。
上記のクエリステートメントが固定実行プランを使用する場合、クエリの応答時間と負荷オーバーヘッドは大幅に最適化されません。 クエリのパフォーマンスが低下することさえあります。
最適化時間が非常に長いSQL文のクエリパフォーマンスを向上させ、システム負荷を軽減し、SQL文の実行時に固定実行プランによって引き起こされるクエリパフォーマンスの低下を回避するために、PolarDB for MySQLは自動プランキャッシュ機能を起動します。 自動プランキャッシュ機能は、auto、DEMAND、ENFORCEの3つのモードをサポートしています。 loose_plan_cache_type
パラメーターを設定して、プランキャッシュにSQL文の実行プランをキャッシュし、最適化時間を短縮し、クエリのパフォーマンスを向上させることで、1つを選択できます。 プランキャッシュ変更またはDDL操作でキャッシュされた実行プランで参照されるテーブルの統計が、プランキャッシュにキャッシュされた実行プランによって参照されるテーブルに対して実行されると、キャッシュされた実行プランは自動的に無効になります。
前提条件
PolarDBクラスターでは、次のいずれかのバージョンを使用します。
リビジョンバージョンが8.0.1.1.33以降のPolarDB for MySQL 8.0.1のクラスター。
リビジョンバージョンが8.0.2.2.12以降のPolarDB for MySQL 8.0.2のクラスター。
パラメーター
PolarDB コンソールで次のパラメーターを設定できます。 詳細については、「クラスターとノードパラメーターの設定」をご参照ください。
パラメーター | 説明 |
loose_plan_cache_type | 自動計画キャッシュモード。 有効な値:
|
loose_plan_cache_expire_time | 実行プランがヒットしないときにプランキャッシュが再利用されるまでの期間。 単位は秒です。 有効値: 0〜UINT_MAX。 デフォルト値: 1800 |
loose_auto_plan_cache_pct_threshold | 全体の実行時間に対するSQL文の最適化時間の比率を指定します。 有効値: 0~100。 デフォルト値は 20 です。 |
loose_auto_plan_cache_time_threshold | SQL文の指定された全体の実行時間。 単位:マイクロ秒。 有効値: 0〜ULONG_MAX。 デフォルト値: 400 |
loose_auto_plan_cache_count_threshold |
有効値: 0〜ULONG_MAX。 デフォルト値: 512 説明 キャッシュされた実行プランは、キャッシュされた実行プランに対して許可された操作の数が |
ストアドプロシージャ
dbms_sql.add_plan_cache(schema, query)
: 指定されたSQL文の実行プランをプランキャッシュにキャッシュします。l
oose_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> を満たしたとき? そしてc1 < ?
テンプレートでは、SQL文の実行計画が計画キャッシュにキャッシュされます。dbms_sql.display_plan_cache_table()
: プランキャッシュで参照されるテーブルに関する情報を表示します。 例:CALL dbms_sql.display_plan_cache_table()\G
サンプル結果:
*************************** 1。 行 *************************** SCHEMA_NAME: テスト TABLE_NAME: t_for_plan REF_COUNT: 1 バージョン: 0 バージョン_時間: 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_id
:mysql.sql_sharing
テーブルに格納されている実行プランの行ID値。例
次のSQL文を実行して、プランキャッシュにキャッシュされている実行プランを照会します。
SELECT Id、Schema_name、Type、Digest_text FROM mysql.sql_sharing WHERE Type = 'PLAN_CACHE'\G
サンプル結果:
*************************** 1。 行 *************************** Id: 1 Schema_name: テスト タイプ: PLAN_CACHE Digest_text: SELECT * FROM 't_for_plan 'WHERE 'c1' > ? そして 'c1' < ?
結果は、
row_id
の値が1であることを示します。上記のクエリで取得した実行プランを削除します。
コールdbms_sql.delete_sharing_by_rowid(1);
プランキャッシュのクエリ情報
SQL文の実行計画は、SQL共有モジュールに格納されます。 次のSQL文を実行して、INFORMATION_SCHEMA.SQL_SHARING
テーブルからプランキャッシュの情報を照会できます。
SELECT TYPE、REF_BY、SQL_ID、SCHEMA_NAME、DIGEST_TEXT、PLAN_ID、PLAN、PLAN_EXTRA、EXTRA FROM json_contains(REF_BY、'"PLAN_CACHE"') またはjson_contains(REF_BY、'"PLAN_CACHE(DEMAND)"')\G
例
データを準備します。
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);
自動計画キャッシュモードをDEMANDに設定します。
次のいずれかの方法を使用して、自動計画キャッシュモードを設定できます。
PolarDB コンソールの [パラメーター] ページで、
loose_plan_cache_type
パラメーターを [DEMAND] に設定します。 切断してから、データベースに再接続します。現在のデータベース接続を維持し、次のステートメントを実行して、現在のセッションの
plan_cache_type
パラメーターをDEMAND
に設定します。SET plan_cache_type=需要;
次のステートメントを実行して、指定したSQLステートメントの実行プランをプランキャッシュにキャッシュします。
CALL dbms_sql.add_plan_cache("test" 、"SELECT * FROM t_for_plan WHERE c1 > 1 AND c1 < 10");
クエリ文を実行します。
SELECT * FROM t_for_plan WHERE c1 > 1 AND c1 < 10;
プランキャッシュの情報を照会します。
SELECT TYPE、REF_BY、SQL_ID、SCHEMA_NAME、DIGEST_TEXT、PLAN_ID、PLAN、PLAN_EXTRA、EXTRA FROM json_contains(REF_BY、'"PLAN_CACHE"') またはjson_contains(REF_BY、'"PLAN_CACHE(DEMAND)"')\G
サンプル結果:
*************************** 1。 行 *************************** タイプ: SQL REF_BY: ["PLAN_CACHE(DEMAND)"] SQL_ID: 9jrvksr3wjux6 SCHEMA_NAME: テスト DIGEST_TEXT: SELECT * FROM 't_for_plan 'WHERE 'c1' > ? そして 'c1' < ? PLAN_ID: NULL プラン: NULL PLAN_EXTRA: NULL 追加: {"TRACE_ROW_ID":1} *************************** 2. 行 *************************** タイプ: 計画 REF_BY: ["PLAN_CACHE"] SQL_ID: 9jrvksr3wjux6 SCHEMA_NAME: テスト DIGEST_TEXT: NULL プランID: 08xftakma6pm6 プラン: /* + 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のテーブルがデータベースに作成されます。 各テーブルは4百万行のデータを格納する。 テストで使用されるSQL文は、SELECT id FROM sbtestN WHERE k in (...)
です。 IN LISTの長さは20である。 パフォーマンスは、PSプロトコルと非PSプロトコルの両方で、loose_plan_cache_type
パラメーターがOFF、AUTO、およびENFORCEに設定されている場合にテストされます。 テスト結果:
PSプロトコルのパフォーマンステストの結果を次の図に示します。
次の図は、非PSプロトコルのパフォーマンステストの結果を示しています。
テスト結果は、自動計画キャッシュ機能がPSプロトコルと非PSプロトコルの両方で50% 以上パフォーマンスを向上できることを示しています。