La fonctionnalité auto plan cache de PolarDB for MySQL permet de mettre en cache les plans d'exécution des instructions SQL. Elle réduit le temps d'optimisation des requêtes et améliore leurs performances. Cette rubrique présente le contexte, les prérequis, les paramètres et les interfaces associés à cette fonctionnalité.
Contexte
Le choix d'un plan d'exécution dépend de nombreux facteurs, tels que les statistiques, l'ordre des jointures et les transformations de requêtes. Le temps d'optimisation varie selon les instructions. Pour certaines instructions SQL, ce temps représente une part importante du temps d'exécution total. Si ces instructions s'exécutent fréquemment, un temps d'optimisation élevé accroît la charge du système. La mise en cache et la réutilisation des plans d'exécution réduisent le temps d'optimisation à chaque exécution. Cela améliore les performances des requêtes, diminue la charge de la base de données et augmente le débit.
Pour de nombreuses autres requêtes, le temps d'optimisation est faible, mais le temps d'exécution dépend fortement du plan choisi. Différentes valeurs de paramètres dans une instruction SQL peuvent correspondre à différents plans d'exécution optimaux. Dans certains scénarios, MySQL récupère les données réelles depuis le moteur en fonction des valeurs de paramètres afin de poursuivre l'optimisation.
L'utilisation d'un plan d'exécution fixe pour ces requêtes n'améliore pas nécessairement le temps de réponse ni ne réduit la charge système. Cela peut même entraîner une régression des performances.
PolarDB for MySQL propose la fonctionnalité auto plan cache pour améliorer les performances des instructions SQL dont le temps d'optimisation est long, réduire la charge système et éviter les régressions liées à l'usage de plans d'exécution fixes. Cette fonctionnalité comporte trois modes : AUTO, DEMAND et ENFORCE. Définissez le paramètre loose_plan_cache_type sur l'un de ces modes pour stocker les plans d'exécution dans le cache de plans. Cela réduit le temps d'optimisation et améliore les performances des requêtes. Un plan d'exécution mis en cache s'invalide automatiquement si les statistiques d'une table référencée changent ou si une opération DDL (Data Definition Language) est effectuée sur cette table.
Prérequis
Votre cluster PolarDB doit répondre à l'une des exigences de version suivantes :
PolarDB for MySQL 8.0.1 avec une version de révision 8.0.1.1.33 ou ultérieure.
PolarDB for MySQL 8.0.2 avec une version de révision 8.0.2.2.12 ou ultérieure.
Paramètres
Configurez les paramètres du tableau suivant dans la console PolarDB. Pour plus d'informations, consultez Définir les paramètres de cluster et de nœud.
|
Paramètre |
Description |
|
loose_plan_cache_type |
Mode de fonctionnement de l'auto plan cache. Valeurs valides :
|
|
loose_plan_cache_expire_time |
Si un plan d'exécution présent dans le cache n'est pas utilisé pendant cette durée, sa mémoire est libérée. Unité : secondes. Plage de valeurs : de 0 à 4294967295. Valeur par défaut : 1800. |
|
loose_auto_plan_cache_pct_threshold |
Seuil du pourcentage du temps d'optimisation par rapport au temps d'exécution total d'une instruction. Plage de valeurs : de 0 à 100. Valeur par défaut : 20. |
|
loose_auto_plan_cache_time_threshold |
Seuil du temps d'exécution total d'une instruction SQL. Unité : microsecondes. Plage de valeurs : de 0 à 18446744073709551615. Valeur par défaut : 400. |
|
loose_auto_plan_cache_count_threshold |
Lorsque le paramètre Plage de valeurs : de 0 à 18446744073709551615. Valeur par défaut : 512. Remarque
Le plan d'exécution mis en cache ne prend effet que lorsque le nombre de mises en cache est supérieur ou égal à la valeur du paramètre |
Description des interfaces
-
dbms_sql.add_plan_cache(schema, query): met en cache le plan d'exécution d'une instruction SQL spécifiée.Lorsque le paramètre
loose_plan_cache_typeest défini sur DEMAND, utilisez cette procédure stockée intégrée pour mettre en cache le plan d'exécution d'une instruction SQL spécifique. Exemple :CALL dbms_sql.add_plan_cache("test", "SELECT * FROM t_for_plan WHERE c1 > 1 AND c1 < 10");Après l'exécution de cette instruction, le plan d'exécution est mis en cache pour toute instruction SQL correspondant au modèle
SELECT * FROM t_for_plan WHERE c1 > ? AND c1 < ?. -
dbms_sql.display_plan_cache_table(): affiche les informations relatives aux tables référencées dans le cache de plans actuel. Exemple :CALL dbms_sql.display_plan_cache_table()\GRésultat retourné :
*************************** 1. row *************************** SCHEMA_NAME: test TABLE_NAME: t_for_plan REF_COUNT: 1 VERSION: 0 VERSION_TIME: 2023-03-10 17:21:35.605264Le tableau suivant décrit les champs retournés.
SCHEMA_NAME : nom du schéma contenant la table référencée.
TABLE_NAME : nom de la table référencée.
REF_COUNT : nombre de références à cette table dans le cache de plans.
VERSION : version de la table référencée dans le cache de plans.
VERSION_TIME : date et heure auxquelles la version actuelle de la table a été référencée.
-
dbms_sql.delete_sharing_by_rowid(row_id): supprime le plan d'exécution d'une instruction SQL spécifiée.Le paramètre
row_idcorrespond à l'ID de ligne du plan d'exécution stocké dans la tablemysql.sql_sharing.Example
-
Exécutez la commande suivante pour consulter les informations sur les plans d'exécution présents dans le cache.
SELECT Id, Schema_name, Type, Digest_text FROM mysql.sql_sharing WHERE Type = 'PLAN_CACHE'\GRésultat retourné :
*************************** 1. row *************************** Id: 1 Schema_name: test Type: PLAN_CACHE Digest_text: SELECT * FROM `t_for_plan` WHERE `c1` > ? AND `c1` < ?Le résultat de la requête indique que la valeur de
row_idest 1. -
Supprimez le plan d'exécution obtenu lors de la requête précédente.
CALL dbms_sql.delete_sharing_by_rowid(1);
-
Récupérer les informations du cache de plans
Les plans d'exécution des instructions SQL sont stockés dans le module SQL Sharing. Exécutez l'instruction SQL suivante pour interroger les informations mises en cache via la table INFORMATION_SCHEMA.SQL_SHARING.
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
Example
-
Préparez les données.
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); -
Définissez le mode auto plan cache sur DEMAND.
Vous pouvez définir le mode auto plan cache de deux manières.
Dans la page Parameters de la console PolarDB, définissez le paramètre
loose_plan_cache_typesur DEMAND. Une fois la configuration terminée, déconnectez-vous puis reconnectez-vous à la base de données.-
Dans la connexion actuelle à la base de données, exécutez la commande suivante pour définir le paramètre
plan_cache_typede la session en cours surdemand.SET plan_cache_type=demand;
-
Exécutez la commande suivante pour mettre en cache le plan d'exécution de l'instruction SQL spécifiée.
CALL dbms_sql.add_plan_cache("test", "SELECT * FROM t_for_plan WHERE c1 > 1 AND c1 < 10"); -
Exécutez l'instruction de requête.
SELECT * FROM t_for_plan WHERE c1 > 1 AND c1 < 10; -
Interrogez les informations mises en cache dans le cache de 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)"')\GRésultat retourné :
*************************** 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}}Dans le champ
EXTRA, la sectionPLAN_CACHE_INFOindique les tables référencées, leurs versions ainsi que le nombre de correspondances (hits) du plan d'exécution.
Performances des requêtes
Un test de charge a été réalisé sur un cluster de 8 cœurs et 32 Go de mémoire. La base de données contenait 25 tables, chacune stockant 4 millions de lignes. Le test utilisait l'instruction SQL SELECT id FROM sbtestN WHERE k IN(...), avec une liste IN de longueur 20. Les performances ont été mesurées avec le paramètre loose_plan_cache_type défini successivement sur OFF, AUTO et ENFORCE, sous les protocoles Prepared Statement (PS) et non-PS. Voici les résultats obtenus :
Résultats du test de performance sous le protocole PS :

Résultats du test de performance sous le protocole non-PS :

Ces résultats montrent que la fonctionnalité auto plan cache améliore les performances de plus de 50 %, tant sous le protocole PS que sous le protocole non-PS.