Tous les produits
Search
Centre de documentation

AnalyticDB:Cache de pagination (optimisation des performances pour les requêtes paginées profondes)

Dernière mise à jour :Aug 10, 2026

AnalyticDB for MySQL propose un mécanisme de mise en cache qui accélère les requêtes paginées à grande échelle impliquant des clauses LIMIT, OFFSET et ORDER BY, tout en résolvant la dégradation des performances liée à la pagination profonde. Cette rubrique explique comment utiliser la fonctionnalité de cache de pagination pour optimiser les performances des requêtes paginées, et présente une approche alternative basée sur la pagination par jeu de clés (keyset pagination).

Prérequis

Un cluster AnalyticDB for MySQL de version mineure 3.2.3 ou ultérieure doit être créé.

Remarque

Présentation

Problèmes de performance causés par les requêtes paginées profondes

Les utilisateurs des plateformes de e-commerce souhaitent trier les produits selon le volume des ventes ou des scores composites afin de mettre en avant les articles de qualité. La plupart du temps, les applications affichent les résultats via une méthode de pagination pour accélérer le temps de réponse des pages et éviter les problèmes de performance liés au chargement simultané de grandes quantités de données.

Une méthode courante dans les bases de données consiste à trier les données selon une colonne et à exécuter des requêtes paginées à l'aide des clauses LIMIT et OFFSET. La clause LIMIT indique le nombre d'entrées affichées par page, tandis que la clause OFFSET définit le décalage de départ des données pour chaque page. Par exemple, si vous souhaitez afficher 100 entrées par page, exécutez la requête suivante pour interroger la première page : SELECT * FROM t_order ORDER BY id LIMIT 0, 100. Pour interroger la page 10 001, exécutez cette requête : SELECT * FROM t_order ORDER BY id LIMIT 1000000, 100.

Lorsque vous effectuez des requêtes paginées sur de grands volumes de données, une requête paginée profonde peut considérablement dégrader les performances de la base de données en raison des coûts liés au tri global et aux opérations de recherche fréquentes. Ce problème est encore plus complexe dans AnalyticDB for MySQL. Afin de réduire la quantité de données brassées entre les différents nœuds, chaque nœud de stockage effectue un calcul topN, et le nœud Gather agrège les résultats d'exécution de tous les nœuds de stockage pour obtenir l'ensemble de résultats final.

image

Pour garantir l'exactitude de l'ensemble de résultats final, le système doit distribuer les instructions SQL réécrites à chaque nœud de stockage pour exécution. Par exemple, pour interroger les entrées de la page 10 001, chaque nœud de stockage reçoit l'instruction SQL suivante : SELECT * FROM t_order ORDER BY id LIMIT 0, 1000100. Par conséquent, le nœud Gather doit trier 1 000 100 × Nombre de nœuds de stockage entrées de données afin d'en extraire seulement 100.

Le volume de données triées augmente linéairement avec la profondeur de la pagination, ce qui entraîne une chute brutale des performances. Cela impose une charge importante sur les ressources mémoire et CPU, augmentant ainsi le risque d'erreurs de type out of memory (OOM). Tel est le problème de performance engendré par les requêtes paginées profondes.

Important

Dans les clusters AnalyticDB for MySQL Enterprise Edition, les données sont réparties sur plusieurs nœuds de stockage. Les requêtes paginées nécessitent un brassage de données inter-nœuds et un tri global, ce qui amplifie davantage la surcharge de performance de la pagination profonde par rapport aux bases de données mono-nœud. Les clusters AnalyticDB for MySQL Basic Edition reposent sur une architecture mono-nœud. Les problèmes de pagination profonde dans les clusters Basic Edition sont similaires à ceux rencontrés dans les bases de données mono-nœud conventionnelles.

Pour résoudre les problèmes de performance liés aux requêtes paginées profondes, AnalyticDB for MySQL met à disposition la fonctionnalité de cache de pagination. Lors de la première initiation d'une requête paginée, le système interroge les données depuis la base et stocke les résultats dans une table de cache temporaire. Lorsque vous lancez des requêtes paginées ultérieures partageant le même modèle SQL, le système lit les données directement depuis la table de cache temporaire, évitant ainsi les opérations de tri répétitives. Cette approche résout efficacement le problème de performance des requêtes paginées profondes et prévient les erreurs OOM provoquées par la clause ORDER BY. AnalyticDB for MySQL supprime automatiquement les données mises en cache devenues inutiles, selon la politique d'éviction, afin d'assurer une utilisation optimale des ressources.

La fonctionnalité de cache de pagination convient aux scénarios suivants :

  • Exportation de grandes quantités de données

    Lors de l'exportation de volumes importants de données, le client peut devenir instable. Dans ce cas, le système exécute des requêtes paginées pour extraire les résultats par lots. Si vous utilisez les clauses LIMIT et OFFSET, l'environnement distribué ne garantit pas un ordre de traitement spécifique des données. Chaque interrogation des données d'une même page peut renvoyer des résultats différents. Il devient alors nécessaire d'utiliser la clause ORDER BY pour éviter les doublons ou les pertes de données. La fonctionnalité de cache de pagination permet de supprimer la clause ORDER BY inutile. Cela améliore considérablement les performances des requêtes et réduit le risque d'erreurs OOM.

  • Requête paginée sur l'intégralité des données

    Les résultats complets de la requête sont mis en cache dans l'espace de stockage chaud d'AnalyticDB for MySQL. Cela garantit la disponibilité des données et augmente significativement la vitesse d'interrogation. Vous pouvez exploiter la fonctionnalité de cache de pagination pour obtenir et afficher les informations page par page.

  • Contrôle de concurrence pour les rapports métier

    Si plusieurs requêtes sont lancées simultanément sur le même rapport, les demandes indépendantes accroissent la charge du cluster et peuvent entraîner des incohérences de données. Utilisez la fonctionnalité de cache de pagination pour effectuer une seule requête au sein d'une fenêtre temporelle donnée, améliorant ainsi les performances des requêtes et la stabilité du cluster.

Utilisation

Configurer une base de données de cache

Avant d'utiliser la fonctionnalité de cache de pagination pour mettre en cache les résultats de requête, nous vous recommandons de spécifier une base de données destinée à stocker les tables de cache temporaires utilisées pour les requêtes paginées. Si aucune base de données n'est spécifiée, les tables de cache temporaires seront stockées dans la base de données interne connectée. Lorsque vous activez la fonctionnalité de cache de pagination, une table de cache temporaire est créée automatiquement.

Remarque

Il n'est pas possible de spécifier une base de données externe comme base de données de cache.

Par exemple, vous pouvez désigner la base de données paging_cache comme base de données de cache. D'autres bases de données peuvent également être spécifiées.

SET ADB_CONFIG PAGING_CACHE_SCHEMA=paging_cache;

Activer la fonctionnalité de cache de pagination pour les requêtes paginées

Si plusieurs requêtes paginées partagent le même modèle SQL, ajoutez un hint (indicateur) aux instructions SQL pour améliorer les performances. Lors de la première initiation d'une requête paginée contenant un hint, le système crée une table de cache temporaire afin de stocker les résultats de la requête paginée. Lorsque vous lancez des requêtes paginées ultérieures utilisant le même modèle SQL, incluez le même hint dans les instructions SQL. Le système lira alors les données depuis la table de cache temporaire, sans avoir besoin d'accéder de nouveau à la base de données.

Limites

Après suppression des clauses LIMIT et OFFSET, le nombre d'entrées de données sur lesquelles vous souhaitez effectuer des requêtes paginées doit être inférieur à 100 millions.

Remarque

Si le nombre d'entrées de données à interroger dépasse 100 millions, Soumettez un ticket pour ajuster la limite supérieure du nombre d'entrées de données.

Méthodes pour activer la fonctionnalité de cache de pagination

Vous pouvez utiliser l'un des hints suivants pour activer la fonctionnalité de cache de pagination :

  • paging_id=<paging_id>

    Le paramètre paging_id spécifie la table de cache créée pour un ensemble de requêtes paginées partageant le même modèle SQL, mais avec des valeurs différentes dans les clauses LIMIT et OFFSET. Le client doit générer un identifiant unique pour identifier de manière distinctive une table de cache correspondant à un ensemble de requêtes paginées.

    • Si le paramètre paging_id spécifié n'existe pas, une table de cache est créée.

    • Si le paramètre paging_id interrogé existe et que le modèle SQL impliqué dans la requête correspond au modèle SQL associé au paramètre paging_id, la requête atteint le cache (cache hit).

    • Si le paramètre paging_id interrogé existe, mais que le modèle SQL impliqué dans la requête ne correspond pas au modèle SQL associé au paramètre paging_id, une erreur se produit. Vérifiez si le paramètre paging_id est déjà utilisé. Pour plus d'informations, consultez la section « Interroger les informations relatives aux tables de cache » de cette rubrique.

    Remarque

    Le paramètre paging_id doit respecter les conventions de nommage suivantes : le nom du paramètre doit comporter entre 1 et 127 caractères et peut contenir des lettres, des chiffres et des traits de soulignement (_). Le nom du paramètre doit commencer par une lettre ou un trait de soulignement (_). Il ne doit pas contenir de guillemets simples ('), de guillemets doubles ("), de points d'exclamation (!) ni d'espaces. Le nom du paramètre ne peut pas être un mot réservé SQL.

    Par exemple, vous pouvez définir l'identifiant de pagination sur paging123 pour le résultat d'un ensemble de requêtes paginées utilisant la fonctionnalité de cache de pagination.

    /*paging_id=paging123*/ SELECT * FROM t_order ORDER BY id LIMIT 0, 100;
  • paging_cache_enabled=true

    Cette méthode ne nécessite pas de modifications fréquentes des hints. Le serveur utilise le modèle SQL excluant les clauses LIMIT et OFFSET pour générer un identifiant de pagination permettant d'identifier un ensemble de requêtes paginées.

    La dépendance vis-à-vis de la correspondance des modèles SQL limite la flexibilité de cette méthode. Si aucune table de cache n'existe pour les requêtes paginées partageant le même modèle SQL (hors clauses LIMIT et OFFSET), une table de cache est créée. Si une table de cache existe déjà pour ces requêtes paginées, elle sera utilisée pour interroger les données.

    Exemple d'instruction :

    /*paging_cache_enabled=true*/ SELECT * FROM t_order ORDER BY id LIMIT 0, 100;

Si la création d'une table de cache échoue, vous devez effacer les données de cache des requêtes paginées et relancer une requête paginée afin de créer une nouvelle table de cache.

Interroger les informations relatives aux tables de cache

Vous pouvez consulter les informations concernant toutes les tables de cache des requêtes paginées au sein du cluster actuel, telles que l'identifiant de pagination, la taille du cache et l'état du cache.

SELECT * FROM INFORMATION_SCHEMA.KEPLER_PAGING_CACHE_STATUS_MERGED;

Spécifier le nombre maximal de tables de cache

Vous pouvez spécifier le nombre maximal de tables de cache au sein du cluster actuel. La valeur par défaut est 32.

SET ADB_CONFIG PAGING_CACHE_MAX_TABLE_COUNT=32;

Si vous tentez de créer une table de cache alors que le nombre total de tables de cache dépasse la limite, une erreur se produit. Exemple de message d'erreur :

Paging cache count exceeds the limit. Please clean up unused caches or increase the related parameter using SET ADB_CONFIG PAGING_CACHE_MAX_TABLE_COUNT=xxx.

Effacez les données de cache devenues inutiles ou augmentez le nombre maximal de tables de cache, en suivant les indications du message d'erreur.

Spécifier une durée de validité pour une table de cache

Vous pouvez spécifier une durée de validité pour une table de cache, exprimée en secondes. Une fois cette période écoulée, la table de cache devient invalide. Lorsque vous lancez des requêtes paginées ultérieures partageant le même modèle SQL, le système accède à la base de données et met à jour la table de cache. Généralement, il est recommandé de spécifier une durée de validité pour une table de cache dans les scénarios de contrôle de concurrence des rapports.

Par exemple, utilisez le hint /*paging_cache_enabled=true, paging_cache_validity_interval=300*/ pour rendre une table de cache valide pendant 300 secondes après sa création. Exemple d'instruction :

/*paging_cache_enabled=true, paging_cache_validity_interval=300*/ SELECT * FROM t_order ORDER BY id LIMIT 0, 100;

Effacer les données de cache des requêtes paginées

Lorsque vous utilisez la fonctionnalité de cache de pagination pour mettre en cache les résultats des requêtes paginées, les données sont stockées dans l'espace de stockage chaud d'AnalyticDB for MySQL. Si certaines données mises en cache ne sont plus nécessaires, effacez-les afin d'augmenter l'espace de stockage disponible.

Effacement manuel

  • Données de cache des requêtes paginées spécifiées par un modèle SQL

    Utilisez le hint /*paging_cache_enabled=true, invalidate_paging_cache=true*/ pour effacer les données de cache des requêtes paginées spécifiées par un modèle SQL.

    Exemple d'instruction :

    /*paging_cache_enabled=true,invalidate_paging_cache=true*/ SELECT * FROM t_order ORDER BY id LIMIT 0, 100;
  • Données de cache des requêtes paginées spécifiées par le paramètre paging_id**

    Effacez les données de cache des requêtes paginées spécifiées par le paramètre paging_id.

    Exemple d'instruction :

    CLEAN_PAGING_CACHE paging123;
    Remarque

    Pour savoir comment obtenir la valeur du paramètre paging_id, consultez la section « Interroger les informations relatives aux tables de cache » de cette rubrique.

Effacement automatique

Vous pouvez spécifier un délai d'expiration du cache afin d'effacer les données de cache des requêtes paginées qui n'ont pas été consultées dans l'intervalle de temps défini. La valeur par défaut est 3 600 secondes. Par défaut, les données de cache non consultées pendant 1 heure sont automatiquement effacées.

SET ADB_CONFIG PAGING_CACHE_EXPIRATION_TIME=3600;

Alternative : Pagination par jeu de clés (Keyset pagination)

Si votre scénario métier prend en charge la navigation basée sur un curseur (par exemple, naviguer vers la page suivante ou précédente sans sauter vers une page arbitraire), vous pouvez utiliser la pagination par jeu de clés comme alternative à la pagination traditionnelle basée sur OFFSET. Au lieu d'utiliser OFFSET pour ignorer des lignes, la pagination par jeu de clés emploie une clause WHERE pour filtrer les lignes en fonction de la dernière valeur récupérée. Cela évite la surcharge liée au tri global et au brassage de données inter-nœuds pour les pages profondes.

Par exemple, supposons que la colonne id soit la clé primaire et que la dernière valeur id de la page actuelle soit 1000. Utilisez l'instruction SQL suivante pour interroger la page suivante :

-- Traditional deep pagination (slow)
SELECT * FROM t_order ORDER BY id LIMIT 1000, 100;

-- Keyset pagination (fast, recommended)
SELECT * FROM t_order WHERE id > 1000 ORDER BY id LIMIT 100;

La méthode de pagination par jeu de clés récupère uniquement le lot de lignes suivant directement depuis l'index, sans tri ni saut d'un grand nombre de lignes. Cela élimine la dégradation des performances causée par la pagination profonde. Les performances de la requête restent constantes, quelle que soit la profondeur de la pagination.

Erreurs courantes et dépannage

Échec de la préparation du cache de pagination, cache indisponible

Message d'erreur :

Paging cache prepare failed, and cache is not available. Please use /*paging_cache_enabled=true,invalidate_paging_cache=true*/ to clean the unavailable cache or set a specific pagingId with /*paging_id=xxx*/ to gen a new cache. Note that the old and new cache data may be inconsistent.

Cause : Lorsque vous utilisez la fonctionnalité de cache de pagination pour interroger des données, des exceptions peuvent survenir, telles qu'un redémarrage de nœud ou une mise à l'échelle. Si une requête paginée atteint une table de cache dont la création a échoué, le serveur n'effectue pas d'accès à la base de données ni de recréation automatique de la table de cache. Le serveur renvoie une erreur.

Solution : Pour garantir la cohérence des données, procédez comme suit : Dans les scénarios d'exportation de données, nous vous recommandons d'effacer les données exportées ainsi que les données de cache indisponibles, puis de relancer une requête paginée pour recréer une table de cache. Dans d'autres scénarios, nous vous conseillons d'effacer les données de cache indisponibles ou de spécifier une nouvelle valeur pour le paramètre paging_id, puis de relancer une requête paginée afin de recréer une table de cache.

Comparaison des performances

Utilisez un jeu de données TPC-H de 100 Go pour évaluer l'effet d'optimisation de la fonctionnalité de cache de pagination sur les requêtes paginées dans les scénarios d'exportation de données.

Ce test implique 1 million d'entrées de données exportées. Chaque page contient 100 000 entrées. Exécutez les instructions suivantes pour effectuer des requêtes paginées sur la première page :

-- General paged query without using the paging cache feature
SELECT * FROM lineitem ORDER BY l_orderkey,l_linenumber LIMIT 0,100000;

-- Paged query by using the paging cache feature (ORDER BY eliminated in the data export scenario)
/*paging_cache_enabled=true*/ SELECT * FROM lineitem LIMIT 0,100000;

Résultat du test :

Les requêtes sont exécutées en mode de concurrence unique. Pendant le processus d'exportation des données, le temps de réponse moyen des requêtes paginées générales est de 54 391 ms. Après activation de la fonctionnalité de cache de pagination, le temps de réponse moyen est de 525 ms. Les performances sont améliorées d'environ 103 fois. L'utilisation du CPU et la consommation de mémoire sont considérablement réduites.

La fonctionnalité de cache de pagination réduit significativement le temps de réponse des requêtes paginées lors du processus d'exportation des données et diminue efficacement la consommation des ressources CPU et mémoire.

image.png