Tous les produits
Search
Centre de documentation

PolarDB:Partial Result Cache (PTRC)

Dernière mise à jour :Aug 11, 2026

La fonctionnalité Partial Result Cache (PTRC) de PolarDB for MySQL améliore les performances des requêtes en mettant en cache les jeux de résultats intermédiaires des opérateurs. Cela permet de réduire les calculs redondants pour les opérateurs complexes. Cette rubrique décrit le concept du PTRC, son principe de fonctionnement, sa sélection basée sur le coût et son mécanisme de retour d'information dynamique.

Concepts

Le PTRC met en cache le jeu de résultats d'un opérateur au sein d'une requête. Il peut par exemple stocker les résultats temporaires d'opérateurs tels qu'une sous-requête corrélée ou une jointure en boucle imbriquée. Si le même opérateur est exécuté à nouveau, le système réutilise le résultat mis en cache au lieu de le recalculer.

Le terme « Partial » dans PTRC possède deux significations :

  • Le PTRC met en cache le jeu de résultats intermédiaires d'un ou plusieurs opérateurs d'une requête, et non le résultat final de la requête entière.

  • Il ne conserve pas nécessairement l'intégralité du jeu de résultats intermédiaires d'un opérateur. En raison des limites de mémoire, seule une partie des résultats peut être mise en cache.

Contrairement au cache de requêtes traditionnel, le PTRC opère à une granularité plus fine en accélérant des opérateurs spécifiques au sein d'une requête. Ce cache n'existe que pendant la durée d'exécution de la requête, ce qui élargit son champ d'application. L'optimisation étant interne à une seule requête, elle évite les problèmes de cohérence des données entre les nœuds. Tout opérateur produisant un résultat déterministe pour un ensemble donné de paramètres d'entrée peut utiliser le PTRC. L'optimiseur décide d'activer ou non cette fonctionnalité en fonction du coût estimé.

Principe de fonctionnement

L'idée centrale du PTRC consiste à mettre en cache les jeux de résultats intermédiaires des opérateurs afin d'éviter les exécutions redondantes. Le PTRC peut accélérer un opérateur si celui-ci remplit les conditions suivantes :

  • L'opérateur dépend de paramètres corrélés pour son exécution et est appelé plusieurs fois. C'est le cas notamment des jointures en boucle imbriquée et des sous-requêtes corrélées.

  • Pour les mêmes paramètres corrélés, le résultat de l'opérateur reste toujours identique. Par conséquent, l'opérateur ne doit pas contenir de fonctions non déterministes telles que RANDOM(), NOW() ou des fonctions définies par l'utilisateur (UDF), car cela compromettrait l'exactitude du résultat final.

Les paramètres corrélés sont des paramètres externes dont dépend un opérateur lors de son exécution. Prenons l'exemple d'une jointure t1 join t2 on t1.a = t2.a où la table t1 est la table pilote : chaque ligne de t1 est jointe à la table t2. Dans ce cas, t1.a constitue un paramètre corrélé pour l'opérateur de jointure en boucle imbriquée. Si la colonne t1.a contient de nombreuses valeurs en double, le PTRC réduit les calculs inutiles. De même, dans une sous-requête corrélée, chaque exécution dépend d'une valeur issue de la requête externe.

La requête TPC-H Q17 illustre le fonctionnement du PTRC :

SELECT
        sum(l_extendedprice) / 7.0 AS avg_yearly
FROM
        lineitem,
        part
WHERE
        p_partkey = l_partkey
        AND p_brand = 'Brand#34'
        AND p_container = 'MED BOX'
        AND l_quantity < (
                SELECT
                        0.2 * avg(l_quantity)
                FROM
                        lineitem
                WHERE
                        l_partkey = p_partkey
        );

Le PTRC utilise les paramètres corrélés de l'opérateur comme clé et le résultat d'exécution comme valeur. Pour la requête TPC-H Q17, le format du cache PTRC est le suivant : clé = p_partkey, valeur = [true/false].

La figure suivante présente le flux d'exécution principal du PTRC pour la sous-requête corrélée de TPC-H Q17 :image

À chaque évaluation de la sous-requête corrélée, le système recherche le résultat dans le cache PTRC en utilisant la valeur de p_partkey :

  • En cas d'absence du résultat (cache miss), le système exécute la sous-requête et stocke le résultat dans le cache PTRC.

  • Si le résultat est trouvé (cache hit), le système retourne directement la valeur mise en cache, évitant ainsi une exécution redondante de la sous-requête.

Dans la requête TPC-H Q17, la sous-requête s'exécute après la jointure des tables part et lineitem. Le résultat de cette jointure contient de nombreuses valeurs en double pour p_partkey, qui correspond au paramètre corrélé de la sous-requête. Le PTRC obtient ainsi un taux de réussite du cache très élevé, ce qui génère des gains de performance significatifs.

La commande EXPLAIN permet de consulter le plan d'exécution. La présence d'un opérateur Partial Result Cache avant la sous-requête indique l'utilisation du PTRC. Par exemple, dans la sortie EXPLAIN pour TPC-H Q17, le nœud Partial result cache: keys(part.P_PARTKEY) correspond au cache PTRC.

*************************** 1. row ***************************
EXPLAIN: -> Aggregate: sum(lineitem.L_EXTENDEDPRICE)
    -> Nested loop inner join  (cost=743267.04 rows=509876)
        -> Filter: ((part.P_CONTAINER = 'MED BOX') and (part.P_BRAND = 'Brand#34'))  (cost=204145.06 rows=19096)
            -> Table scan on part  (cost=204145.06 rows=1909557)
        -> Filter: (lineitem.L_QUANTITY < (select #2))  (cost=25.56 rows=27)
            -> Index lookup on lineitem using LINEITEM_FK2 (L_PARTKEY=part.P_PARTKEY)  (cost=25.56 rows=27)
            -> Select #2 (subquery in condition; dependent)
                -> Partial result cache: keys(part.P_PARTKEY)
                    -> Aggregate: avg(lineitem.L_QUANTITY)
                        -> Index lookup on lineitem using LINEITEM_FK2 (L_PARTKEY=part.P_PARTKEY)  (cost=28.23 rows=27)

Prérequis

Votre cluster PolarDB for MySQL doit être en version 8.0, avec une révision 8.0.2.2.9 ou ultérieure. Pour vérifier la version de votre cluster, suivez les instructions décrites dans Versions du moteur de requête.

Paramètres

Paramètre

Niveau

Description

partial_result_cache_enabled

Global/Session

Active ou désactive la fonctionnalité Partial Result Cache (PTRC). Valeurs valides :

  • ON (par défaut) : active le PTRC.

  • OFF : désactive le PTRC.

partial_result_cache_cost_threshold

Global/Session

Seuil de coût pour le PTRC. L'optimiseur n'envisage l'utilisation du PTRC que si le coût total d'une requête dépasse cette valeur.

Plage de valeurs : 0 à 18446744073709551615. Valeur par défaut : 10000.

partial_result_cache_check_frequency

Global/Session

Fréquence de déclenchement du mécanisme de retour d'information dynamique. Une vérification survient lorsque le nombre cumulé de défauts de cache atteint cette valeur.

Plage de valeurs : 0 à 18446744073709551615. Valeur par défaut : 200.

partial_result_cache_low_hit_rate

Global/Session

Seuil inférieur du taux de réussite du cache. L'optimiseur envisage le PTRC uniquement si le taux de réussite estimé dépasse cette valeur. Si le PTRC est déjà actif, le mécanisme de retour d'information dynamique le désactive lorsque le taux réel passe sous ce seuil.

Plage de valeurs : 0 à 100. Valeur par défaut : 20.

partial_result_cache_high_hit_rate

Global/Session

Seuil supérieur du taux de réussite du cache. Lorsque l'utilisation de la mémoire atteint sa limite et que le taux de réussite dépasse cette valeur, le système transfère le cache de la mémoire vers le disque. Les données déjà en cache sont également déplacées.

Plage de valeurs : 0 à 100. Valeur par défaut : 70.

partial_result_cache_max_mem_size

Global/Session

Quantité maximale de mémoire que le PTRC peut allouer pour une seule requête. Si une requête comporte plusieurs opérateurs utilisant le PTRC, leur consommation mémoire combinée ne doit pas excéder cette limite.

Plage de valeurs : 0 à 18446744073709551615. Unité : octets. Valeur par défaut : 67108864.

Sélection basée sur le coût

Comme l'illustre le flux d'exécution du PTRC, son activation n'est pas toujours avantageuse. Son efficacité dépend directement du taux de réussite du cache. Un taux faible entraîne une surcharge de performance due aux opérations de vérification du cache et à une consommation mémoire accrue.

Pour éviter toute surcharge inutile, l'optimiseur adopte une approche basée sur le coût afin de décider d'utiliser ou non le PTRC. Il évalue deux facteurs principaux :

  • L'optimiseur n'envisage le PTRC que si le coût total de la requête dépasse la valeur partial_result_cache_cost_threshold.

  • Le taux de réussite estimé du cache pour l'opérateur doit être supérieur à la valeur partial_result_cache_low_hit_rate.

Lors de sa prise de décision basée sur le coût, l'optimiseur vérifie d'abord le paramètre partial_result_cache_cost_threshold.

  • Si le coût total d'une requête est inférieur à ce seuil, l'optimiseur considère que la requête est peu coûteuse et rapide à exécuter. Le gain de performance apporté par le PTRC serait minime, tandis que la surcharge liée aux vérifications du cache pourrait augmenter la latence des requêtes courtes à forte concurrence. L'optimiseur utilise donc ce seuil de coût global pour contourner entièrement le PTRC pour les requêtes peu coûteuses. Cela lui évite également la surcharge consistant à évaluer l'éligibilité de toutes les expressions au PTRC.

  • Si le coût total de la requête est supérieur ou égal à partial_result_cache_cost_threshold, l'optimiseur évalue tous les opérateurs éligibles au PTRC et estime leur taux de réussite du cache selon la formule suivante :

    hit_rate = (fanout - ndv) / fanout

    Dans cette formule, fanout représente le nombre total d'exécutions attendues pour un opérateur, et ndv correspond au nombre de valeurs distinctes pour la clé PTRC (combinaison de tous les paramètres corrélés).

Si le hit_rate estimé est inférieur à la valeur partial_result_cache_low_hit_rate, l'optimiseur n'utilise pas le PTRC pour cet opérateur. Toutefois, dans le modèle de coût MySQL existant, les statistiques reposent sur les index de table ou les histogrammes. Si les colonnes des paramètres corrélés ne disposent ni d'index ni d'histogramme, l'optimiseur ne peut pas estimer précisément le ndv. Dans ce cas, il peut activer le PTRC de manière proactive et s'appuyer sur le mécanisme de retour d'information dynamique pendant l'exécution pour décider de maintenir ou non son utilisation.

Mécanisme de retour d'information dynamique

Pendant la phase d'exécution, chaque succès ou défaut de cache est enregistré dans les statistiques. Le mécanisme de retour d'information dynamique exploite ces données pour calculer le taux de réussite réel du cache. Si ce taux tombe sous la valeur partial_result_cache_low_hit_rate, le mécanisme désactive immédiatement le PTRC pour le reste de l'exécution. La requête revient alors à son plan d'exécution initial, ce qui réduit la surcharge causée par un cache inefficace.

Le paramètre partial_result_cache_check_frequency contrôle la fréquence de cette vérification dynamique. Il définit le nombre cumulé de défauts de cache déclenchant une analyse. Par exemple, avec la valeur par défaut de 200, le mécanisme de retour d'information se déclenche après 200 défauts de cache.

Le jeu de résultats étant mis en cache en mémoire, le mécanisme de retour d'information dynamique se déclenche également lorsque l'utilisation mémoire du PTRC atteint sa limite. Dans ce scénario, le mécanisme vérifie non seulement si le taux de réussite est trop faible, mais décide aussi d'évincer des données ou de déverser le jeu de résultats sur le disque.

Lorsque l'utilisation mémoire du PTRC atteint sa limite, la politique de retour d'information suivante s'applique :

  1. Si le hit_rate est inférieur à la valeur partial_result_cache_low_hit_rate, le système juge le taux trop faible et désactive le PTRC.

  2. Si le hit_rate dépasse la valeur partial_result_cache_high_hit_rate, le système transfère les données du cache de la mémoire vers le stockage sur disque. Une amélioration prévisible des performances est maintenue même avec un cache sur disque.

  3. Si le hit_rate se situe entre les seuils inférieur et supérieur, le système applique une politique d'éviction LRU (Least Recently Used). Les données les moins récemment utilisées sont supprimées du cache pour libérer de l'espace. Si la limite de mémoire est atteinte à nouveau après la mise en cache de nouvelles données, le processus recommence à l'étape 1.

Le paramètre partial_result_cache_max_mem_size plafonne l'utilisation cumulative de la mémoire pour le PTRC au sein d'une seule requête. Si la mémoire totale consommée par toutes les instances PTRC d'une requête dépasse cette limite, le système déclenche le mécanisme de retour d'information dynamique pour chacune d'elles.

Test de performance

Comme indiqué dans la section sur la sélection basée sur le coût, les principaux facteurs influençant les gains de performance du PTRC sont les suivants :

  • Le coût d'exécution de l'opérateur accéléré doit être suffisamment élevé. Si l'opérateur est peu coûteux, le gain potentiel lié à la mise en cache reste limité.

  • Le taux de réussite du cache doit être élevé, car un taux supérieur engendre des améliorations de performance plus marquées.

Prenons l'exemple du test TPC-H Q17 :

SELECT sum(l_extendedprice) / 7.0 AS avg_yearly
FROM lineitem, part
WHERE p_partkey = l_partkey
    AND p_brand = 'Brand#34'
    AND p_container = 'MED BOX'
    AND l_quantity < (
        SELECT 0.2 * avg(l_quantity)
        FROM lineitem
        WHERE l_partkey = p_partkey
    );

La sous-requête de cette requête s'exécute de nombreuses fois. Le plan d'exécution suivant confirme l'utilisation du PTRC. Dans l'arborescence EXPLAIN pour TPC-H Q17, le nœud Partial result cache: keys(part.P_PARTKEY) indique que le PTRC est appliqué à la sous-requête dépendante :

EXPLAIN: -> Aggregate: sum(lineitem.L_EXTENDEDPRICE)
    -> Nested loop inner join  (cost=743267.04 rows=509876)
        -> Filter: ((part.P_CONTAINER = 'MED BOX') and (part.P_BRAND = 'Brand#34'))  (cost=204145.06 rows=19096)
            -> Table scan on part  (cost=204145.06 rows=1909557)
        -> Filter: (lineitem.L_QUANTITY < (select #2))  (cost=25.56 rows=27)
            -> Index lookup on lineitem using LINEITEM_FK2 (L_PARTKEY=part.P_PARTKEY)  (cost=25.56 rows=27)
            -> Select #2 (subquery in condition; dependent)
                -> Partial result cache: keys(part.P_PARTKEY)
                    -> Aggregate: avg(lineitem.L_QUANTITY)
                        -> Index lookup on lineitem using LINEITEM_FK2 (L_PARTKEY=part.P_PARTKEY)  (cost=28.23 rows=27)

Les statistiques de test révèlent que l'activation du PTRC pour la sous-requête de TPC-H Q17 permet d'atteindre un taux de réussite du cache allant jusqu'à 96 %, ce qui améliore considérablement les performances. La figure suivante présente les données du test :image

Résumé

Le PTRC cible les opérateurs complexes au sein d'une requête unique qui dépendent de paramètres corrélés. En mettant en cache leurs jeux de résultats intermédiaires, il réduit les calculs redondants. Des gains de performance substantiels sont obtenus lorsque le taux de réussite du cache est suffisamment élevé. Actuellement, le PTRC accélère divers opérateurs, notamment les sous-requêtes corrélées et les jointures en boucle imbriquée (couvrant les jointures internes, externes, semi-jointures et anti-jointures). t1