Superviser les performances avec le magasin des requêtes
S’APPLIQUE À : Azure Database pour PostgreSQL : serveur flexible
La fonctionnalité du magasin des requêtes du serveur flexible Azure Database pour PostgreSQL permet de suivre le niveau de performances des requêtes au fil du temps. Le magasin des requêtes simplifie la résolution des problèmes de performances en vous aidant à identifier rapidement les requêtes dont l’exécution est la plus longue et qui consomment le plus de ressources. Le magasin des requêtes capture automatiquement un historique des requêtes et des statistiques d’exécution, et les conserve pour que vous les passiez en revue. Il découpe les données par heure de façon à ce que vous puissiez voir des modèles d’utilisation temporelle. Les données de l’ensemble des utilisateurs, bases de données et requêtes sont stockées dans une base de données nommée azure_sys
dans l’instance du serveur flexible Azure Database pour PostgreSQL.
Activer le magasin des requêtes
Le magasin des requêtes est utilisable sans frais supplémentaires. Il s’agit d’une fonctionnalité avec consentement, elle n’est pas activée par défaut sur un serveur. Le Magasin des requêtes peut être activé ou désactivé de façon globale pour toutes les bases de données se trouvant sur un serveur donné, et ne peut pas être activé ou désactivé par base de données.
Important
N’activez pas le magasin des requêtes sur le niveau tarifaire Burstable, car cela aurait un impact sur les performances.
Activer le magasin des requêtes sur le Portail Azure
- Connectez-vous au portail Azure et sélectionnez votre instance de serveur flexible Azure Database pour PostgreSQL.
- Sélectionnez Paramètres du serveur dans la section Paramètres du menu.
- Recherchez le paramètre
pg_qs.query_capture_mode
. - Définissez la valeur sur
top
ouall
, selon que vous souhaitez effectuer le suivi des requêtes de niveau supérieur ou également des requêtes imbriquées (qui s’exécutent à l’intérieur d’une fonction ou d’une procédure), puis cliquez sur Enregistrer. Patientez jusqu’à 20 minutes pour que le premier lot de données persiste dans la base de donnéesazure_sys
.
Activer l’échantillonnage d’attente du magasin des requêtes
- Recherchez le paramètre
pgms_wait_sampling.query_capture_mode
. - Définissez la valeur sur
all
et cliquez sur Enregistrer.
Informations dans le magasin des requêtes
Le magasin des requêtes se compose de deux magasins :
- Un magasin des statistiques d’exécution pour conserver les informations sur les statistiques d’exécution des requêtes.
- Un magasin des statistiques d’attente pour conserver les informations sur les statistiques d’attente.
Les scénarios courants pour l’utilisation du magasin des requêtes comprennent :
- Détermination du nombre de fois où une requête a été exécutée dans une fenêtre de temps donnée.
- Comparaison de la durée d’exécution moyenne d’une requête sur plusieurs fenêtres de temps pour voir les variations importantes.
- Identification des requêtes durables au cours des dernières heures.
- Identification des N premières requêtes en attente de ressources.
- Comprendre la nature des attentes pour une requête particulière.
Pour réduire l’utilisation de l’espace, les statistiques d’exécution du runtime dans le magasin des statistiques d’exécution sont agrégées pendant une fenêtre de temps configurable fixe. Les informations contenues dans ces magasins peuvent être interrogées à l’aide de vues.
Accéder aux informations du magasin des requêtes
Les données du magasin des requêtes sont stockées dans la base de données azure_sys
sur votre instance de serveur flexible Azure Database pour PostgreSQL.
La requête suivante retourne des informations sur les requêtes enregistrées dans le magasin des requêtes :
SELECT * FROM query_store.qs_view;
Cette requête retourne également des informations sur les statistiques d’attente :
SELECT * FROM query_store.pgms_wait_sampling_view;
Rechercher des requêtes d’attente
Les types d’événements d’attente combinent différents événements d’attente dans des compartiments par similarité. Le magasin des requêtes fournit le type d’événement d’attente, le nom de l’événement d’attente spécifique et la requête en question. Pouvoir mettre en corrélation ces informations d’attente avec les statistiques d’exécution de requête vous permet de mieux comprendre ce qui contribue aux caractéristiques de performances des requêtes.
Voici quelques exemples illustrant la façon d’obtenir plus d’informations dans votre charge de travail à l’aide des statistiques d’attente dans le magasin des requêtes :
Observation | Action |
---|---|
Attentes de verrous élevés | Vérifiez les textes de requêtes pour les requêtes affectées et identifiez les entités cibles. Recherchez dans le magasin des requêtes d’autres requêtes qui sont fréquemment exécutées et/ou ont une durée importante et modifient la même entité. Après avoir identifié ces requêtes, envisagez de changer la logique d’application pour améliorer l’accès concurrentiel, ou utilisez un niveau d’isolation moins restrictif. |
Attentes d’E/S de mémoire tampon élevées | Recherchez les requêtes comportant un grand nombre de lectures physiques dans le magasin des requêtes. Si elles correspondent aux requêtes avec des attentes d’E/S élevées, envisagez d’activer la fonctionnalité d’optimisation automatisée des index pour voir si elle peut recommander la création de certains index susceptibles de diminuer le nombre de lectures physiques pour ces requêtes. |
Attentes de mémoire élevée | Recherchez les requêtes qui consomment le plus de mémoire dans le magasin des requêtes. Ces requêtes retardent probablement davantage la progression des requêtes affectées. |
Options de configuration
Lorsque le magasin des requêtes est activé, il enregistre les données dans des fenêtres d’agrégation de longueur déterminée par le paramètre de serveur pg_qs.interval_length_minutes (défini par défaut à 15 minutes). Pour chaque fenêtre, il stocke jusqu’à 500 requêtes distinctes. Les attributs qui distinguent l’unicité de chaque requête sont user_id (identificateur de l’utilisateur qui exécute la requête), db_id (identificateur de la base de données dans le contexte de laquelle la requête s’exécute) et query_id (valeur entière identifiant de manière unique la requête exécutée). Si le nombre de requêtes distinctes atteint 500 pendant l’intervalle configuré, 5 % des requêtes enregistrées sont libérées pour laisser la place à d’autres. Les requêtes libérées en premier sont celles qui ont été exécutées le moins de fois.
Les options suivantes sont disponibles pour la configuration des paramètres du Magasin des requêtes :
Paramètre | Description | Par défaut | Plage |
---|---|---|---|
pg_qs.interval_length_minutes (*) |
Intervalle de capture du magasin des requêtes (en minutes). Définit la fréquence de persistance des données. | 15 |
1 - 30 |
pg_qs.is_enabled_fs |
Utilisation interne uniquement : ce paramètre est utilisé comme commutateur de remplacement de fonctionnalité. S’il apparaît désactivé, le magasin des requêtes est désactivé malgré la valeur définie pour pg_qs.query_capture_mode . |
on |
on , off |
pg_qs.max_plan_size |
Nombre maximal d’octets enregistrés à partir du texte du plan de requête par magasin des requêtes. Les plans plus longs sont tronqués. | 7500 |
100 - 10000 |
pg_qs.max_query_text_length |
Longueur maximale de requête qui peut être enregistrée. Les requêtes plus longues sont tronquées. | 6000 |
100 - 10000 |
pg_qs.parameters_capture_mode |
Indique si et quand capturer les paramètres positionnels de requête. | capture_parameterless_only |
capture_parameterless_only , capture_first_sample |
pg_qs.query_capture_mode |
Instructions à suivre. | none |
none , top , all |
pg_qs.retention_period_in_days |
Fenêtre de période de rétention en jours pour le magasin des requêtes. Les données plus anciennes sont automatiquement supprimées. | 7 |
1 - 30 |
pg_qs.store_query_plans |
Indique si les plans de requête doivent être enregistrés dans le magasin des requêtes. | off |
on , off |
pg_qs.track_utility |
Indique si le magasin des requêtes doit suivre les commandes utilitaires. | on |
on , off |
(*) Paramètre statique du serveur qui nécessite un redémarrage du serveur pour qu’une modification de sa valeur prenne effet.
Les options suivantes s’appliquent spécifiquement aux statistiques d’attente :
Paramètre | Description | Par défaut | Plage |
---|---|---|---|
pgms_wait_sampling.history_period |
Fréquence, en millisecondes, à laquelle les événements d’attente sont échantillonnés. | 100 |
1 - 600000 |
pgms_wait_sampling.is_enabled_fs |
Utilisation interne uniquement : ce paramètre est utilisé comme commutateur de remplacement de fonctionnalité. Si elle apparaît comme off , l’échantillonnage d’attente est désactivé malgré la valeur définie pour pgms_wait_sampling.query_capture_mode . |
on |
on , off |
pgms_wait_sampling.query_capture_mode |
Les instructions que l’extension pgms_wait_sampling doit suivre. |
none |
none , all |
Remarque
pg_qs.query_capture_mode
est prioritaire sur pgms_wait_sampling.query_capture_mode
. Si pg_qs.query_capture_mode
est none
, le paramètre pgms_wait_sampling.query_capture_mode
n’a pas d’effet.
Utilisez le portail Azure pour obtenir ou définir une valeur différente pour un paramètre.
Vues et fonctions
Vous pouvez interroger les informations enregistrées par le magasin des requêtes et les supprimer à l’aide de certaines vues et fonctions disponibles dans le schéma query_store
de la base de données azure_sys
. Quiconque dans le rôle public PostgreSQL peut utiliser ces vues pour afficher les données du magasin des requêtes. Ces vues sont disponibles uniquement dans la base de données azure_sys.
Les requêtes sont normalisées en examinant leur structure et en ignorant tout ce qui n’est pas sémantiquement significatif, comme les littéraux, les constantes, les alias ou les différences de casse.
Si deux requêtes sont sémantiquement identiques, même si elles utilisent des alias différents pour les mêmes colonnes et tables référencées, elles sont identifiées par le même query_id. Si deux requêtes diffèrent uniquement dans les valeurs littérales utilisées, elles sont également identifiées avec la même query_id. Pour les requêtes identifiées avec le même query_id, leur sql_query_text est celui de la requête exécutée en premier depuis le démarrage de l’activité d’enregistrement du magasin des requêtes, ou depuis la dernière fois que les données persistantes ont été ignorées à l’exécution de la fonction query_store.qs_reset.
Fonctionnement de la normalisation des requêtes
Voici quelques exemples pour essayer d’illustrer le fonctionnement de cette normalisation :
Supposons que vous créiez une table avec l’instruction suivante :
create table tableOne (columnOne int, columnTwo int);
Vous activez la collecte de données du Magasin des requêtes et un ou plusieurs utilisateurs exécutent les requêtes suivantes, dans l’ordre exact :
select * from tableOne;
select columnOne, columnTwo from tableOne;
select columnOne as c1, columnTwo as c2 from tableOne as t1;
select columnOne as "column one", columnTwo as "column two" from tableOne as "table one";
Toutes les requêtes précédentes partagent les mêmes query_id. Et le texte conservé par le Magasin des requêtes est celui de la première requête exécutée après l’activation de la collecte de données. Par conséquent, il serait select * from tableOne;
.
L’ensemble de requêtes suivant, une fois normalisé, ne correspond pas au jeu de requêtes précédent, car la clause WHERE les rend sémantiquement différentes :
select columnOne as c1, columnTwo as c2 from tableOne as t1 where columnOne = 1 and columnTwo = 1;
select * from tableOne where columnOne = -3 and columnTwo = -3;
select columnOne, columnTwo from tableOne where columnOne = '5' and columnTwo = '5';
select columnOne as "column one", columnTwo as "column two" from tableOne as "table one" where columnOne = 7 and columnTwo = 7;
Toutefois, toutes les requêtes de ce dernier jeu partagent les mêmes query_id et le texte utilisé pour les identifier tous est celui de la première requête dans le lot select columnOne as c1, columnTwo as c2 from tableOne as t1 where columnOne = 1 and columnTwo = 1;
.
Enfin, recherchez ci-dessous certaines requêtes qui ne correspondent pas au query_id de celles du lot précédent, et la raison pour laquelle elles ne correspondent pas :
Requête :
select columnTwo as c2, columnOne as c1 from tableOne as t1 where columnOne = 1 and columnTwo = 1;
Raison de ne pas correspondre : la liste des colonnes fait référence aux deux mêmes colonnes (ColonneUn et ColonneDeux), mais l’ordre dans lequel elles sont référencées est inversé, de columnOne, ColumnTwo
dans le lot précédent à ColumnTwo, columnOne
dans cette requête.
Requête :
select * from tableOne where columnTwo = 25 and columnOne = 25;
Raison de ne pas correspondre : Ordre dans lequel les expressions évaluées dans la clause WHERE sont référencées sont inversées de columnOne = ? and ColumnTwo = ?
dans le lot précédent pour ColumnTwo = ? and columnOne = ?
dans cette requête.
Requête :
select abs(columnOne), columnTwo from tableOne where columnOne = 12 and columnTwo = 21;
Raison de ne pas correspondre : la première expression de la liste de colonnes n’est plus columnOne
, mais la fonction abs
évaluée sur columnOne
(abs(columnOne)
), qui n’est pas sémantiquement équivalente.
Requête :
select columnOne as "column one", columnTwo as "column two" from tableOne as "table one" where columnOne = ceiling(16) and columnTwo = 16;
Raison de ne pas correspondre : la première expression de la clause WHERE n’évalue plus l’égalité de columnOne
avec un littéral, mais avec le résultat de la fonction ceiling
évaluée sur un littéral, ce qui n’est pas sémantiquement équivalent.
Vues
query_store.qs_view
Cette vue retourne toutes les données persistantes dans les tables de prise en charge du magasin des requêtes. Les données toujours enregistrées en mémoire pour la fenêtre de temps actuellement active ne sont pas visibles tant que la fenêtre de temps n’est pas terminée et que ses données volatiles en mémoire ne sont pas collectées et conservées sur des tables stockées sur le disque. Cette vue retourne une ligne différente pour chaque base de données distincte (db_id), l’utilisateur(-trice) (user_id) et la requête (query_id).
Nom | Type | Informations de référence | Description |
---|---|---|---|
runtime_stats_entry_id |
bigint | ID de la table runtime_stats_entries. | |
user_id |
oid | pg_authid.oid | OID de l’utilisateur(-trice) qui a exécuté l’instruction. |
db_id |
oid | pg_database.oid | OID de la base de données dans laquelle l’instruction a été exécutée. |
query_id |
bigint | Code de hachage interne, calculé à partir de l’arborescence d’analyse de l’instruction. | |
query_sql_text |
varchar(10000) | Texte d’une instruction représentative. Différentes requêtes ayant la même structure sont regroupées en clusters ; ce texte est le texte de la première des requêtes du cluster. La valeur par défaut de la longueur maximale du texte de la requête est de 6000, et peut être modifiée à l’aide du paramètre du Magasin des requêtes pg_qs.max_query_text_length . Si le texte de la requête dépasse cette valeur maximale, il est tronqué aux pg_qs.max_query_text_length premiers caractères. |
|
plan_id |
bigint | ID du plan correspondant à cette requête. | |
start_time |
timestamp | Les requêtes sont agrégées par fenêtres de temps. Le paramètre de serveur pg_qs.interval_length_minutes définit l’intervalle de temps de ces fenêtres (la valeur par défaut est de 15 minutes). Cette colonne correspond à l’heure de début de la fenêtre dans laquelle cette entrée a été enregistrée. |
|
end_time |
timestamp | Heure de fin correspondant à la fenêtre de temps pour cette entrée. | |
calls |
bigint | Nombre de fois où la requête a été exécutée dans cette fenêtre temporelle. Notez que pour les requêtes parallèles, le nombre d’appels pour chaque exécution correspond à 1 pour le processus backend pilotant l’exécution de la requête, plus une unité par processus Worker backend lancé pour collaborer à l’exécution des branches parallèles de l’arborescence d’exécution. | |
total_time |
double précision | Durée totale d’exécution de la requête, en millisecondes. | |
min_time |
double précision | Durée minimale d’exécution de la requête, en millisecondes. | |
max_time |
double précision | Durée maximale d’exécution de la requête, en millisecondes. | |
mean_time |
double précision | Durée moyenne d’exécution de la requête, en millisecondes. | |
stddev_time |
double précision | Écart type de la durée d’exécution de la requête, en millisecondes. | |
rows |
bigint | Nombre total de lignes récupérées ou affectées par l’instruction. Notez que pour les requêtes parallèles, le nombre de lignes pour chaque exécution correspond au nombre de lignes renvoyées au client par le processus backend qui pilote l’exécution de la requête, plus la somme de toutes les lignes que chaque processus Worker backend, lancé pour collaborer à l’exécution des branches parallèles de l’arborescence d’exécution, renvoie au processus backend qui pilote l’exécution de la requête. | |
shared_blks_hit |
bigint | Nombre total d’accès au cache de blocs partagés par l’instruction. | |
shared_blks_read |
bigint | Nombre total de blocs partagés lus par l’instruction. | |
shared_blks_dirtied |
bigint | Nombre total de blocs partagés modifiés par l’instruction. | |
shared_blks_written |
bigint | Nombre total de blocs partagés écrits par l’instruction. | |
local_blks_hit |
bigint | Nombre total d’accès au cache de blocs locaux par l’instruction. | |
local_blks_read |
bigint | Nombre total de blocs locaux lus par l’instruction. | |
local_blks_dirtied |
bigint | Nombre total de blocs locaux modifiés par l’instruction. | |
local_blks_written |
bigint | Nombre total de blocs locaux écrits par l’instruction. | |
temp_blks_read |
bigint | Nombre total de blocs temporaires lus par l’instruction. | |
temp_blks_written |
bigint | Nombre total de blocs temporaires écrits par l’instruction. | |
blk_read_time |
double précision | Durée totale passée par l’instruction à lire des blocs, en millisecondes (si track_io_timing est activé ; sinon, zéro). | |
blk_write_time |
double précision | Durée totale passée par l’instruction à écrire des blocs, en millisecondes (si track_io_timing est activé ; sinon, zéro). | |
is_system_query |
booléen | Détermine si le rôle avec user_id = 10 (azuresu) a exécuté la requête. Cet utilisateur dispose de privilèges de superutilisateur et est utilisé pour effectuer des opérations de plan de contrôle. Étant donné que ce service est un service PaaS managé, seule Microsoft fait partie du rôle de super-utilisateur(-trice). | |
query_type |
texte | Type d’opération représenté par la requête. Les valeurs possibles sont les suivantes : unknown , select , update , insert , delete , merge , utility , nothing , undefined . |
|
search_path |
texte | Valeur de search_path définie au moment de la capture de la requête. | |
query_parameters |
texte | Représentation textuelle d’un objet JSON avec les valeurs passées aux paramètres positionnels d’une requête paramétrisée. Cette colonne remplit uniquement sa valeur dans deux cas : 1) pour les requêtes non paramétrisées. 2) Pour les requêtes paramétrisées, lorsque pg_qs.parameters_capture_mode est défini sur capture_first_sample , et si le magasin des requêtes peut extraire les valeurs des paramètres de la requête au moment de l’exécution. |
|
parameters_capture_status |
texte | Type d’opération représenté par la requête. Les valeurs possibles sont succeeded (la requête n’était pas paramétrisée ou il s’agissait d’une requête paramétrisée et les valeurs ont été capturées avec succès), disabled (la requête était paramétrisée, mais les paramètres n’ont pas été capturés, car pg_qs.parameters_capture_mode était défini sur capture_parameterless_only ), too_long_to_capture (la requête était paramétrisée, mais les paramètres n’ont pas été capturés, car la longueur du JSON résultant qui serait exposé dans la colonne query_parameters de cette vue, a été considéré comme excessivement long pour la persistance du magasin des requêtes), too_many_to_capture (la requête était paramétrisée, mais les paramètres n’ont pas été capturés, car le nombre total de paramètres était considéré comme excessif pour la persistance du magasin des requêtes), serialization_failed (la requête était paramétrisée, mais au moins l’une des valeurs passées en tant que paramètre n’a pas pu être sérialisée en texte). |
query_store.query_texts_view
Cette vue retourne les données du texte des requêtes du Magasin des requêtes. Il y a une ligne pour chaque query_sql_text distinct.
Nom | Type | Description |
---|---|---|
query_text_id |
bigint | ID de la table query_texts |
query_sql_text |
varchar(10000) | Texte d’une instruction représentative. Différentes requêtes ayant la même structure sont regroupées en clusters ; ce texte est le texte de la première des requêtes du cluster. |
query_type |
smallint | Type d’opération représenté par la requête. Dans la version de PostgreSQL <= 14, les valeurs possibles sont 0 (inconnu), 1 (sélectionner), 2 (mise à jour), 3 (insérer), 4 (supprimer), 5 (utilitaire), 6 (rien). Dans la version de PostgreSQL >= 15, les valeurs possibles sont 0 (inconnu), 1 (sélectionner), 2 (mise à jour), 3 (insérer), 4 (supprimer), 5 (fusionner), 6 (utilitaire), 7 (rien). |
query_store.pgms_wait_sampling_view
Cette vue retourne les données des événements d’attente du Magasin des requêtes. Cette vue renvoie une ligne différente pour chaque base de données (db_id), utilisateur(-trice) (user_id), requête (query_id) et événement (event).
Nom | Type | Informations de référence | Description |
---|---|---|---|
start_time |
timestamp | Les requêtes sont agrégées par fenêtres de temps. Le paramètre de serveur pg_qs.interval_length_minutes définit l’intervalle de temps de ces fenêtres (la valeur par défaut est de 15 minutes). Cette colonne correspond à l’heure de début de la fenêtre dans laquelle cette entrée a été enregistrée. |
|
end_time |
timestamp | Heure de fin correspondant à la fenêtre de temps pour cette entrée. | |
user_id |
oid | pg_authid.oid | OID de l’utilisateur qui a exécuté l’instruction. |
db_id |
oid | pg_database.oid | OID de la base de données dans laquelle l’instruction a été exécutée. |
query_id |
bigint | Code de hachage interne, calculé à partir de l’arborescence d’analyse de l’instruction. | |
event_type |
texte | Type d’événement pour lequel le backend est en attente. | |
event |
texte | Nom de l’événement d’attente si le backend est actuellement en attente. | |
calls |
entier | Nombre de fois où le même événement a été capturé. |
Remarque
Pour obtenir la liste des valeurs possibles dans les colonnes event_type
et event
de la vue query_store.pgms_wait_sampling_view
, reportez-vous à la documentation officielle de pg_stat_activity et recherchez les informations faisant référence aux colonnes portant les mêmes noms.
query_store.query_plans_view
Cette vue retourne le plan de requête utilisé pour exécuter une requête. Il y a une ligne par ID de base de données distinct, ID d’utilisateur et ID de requête. Le magasin des requêtes enregistre uniquement les plans de requête pour les requêtes non utilitaires.
Nom | Type | Informations de référence | Description |
---|---|---|---|
plan_id |
bigint | Valeur de hachage du plan de requête normalisé produit par EXPLAIN. Il est sous forme normalisée, car il exclut les coûts estimés des nœuds de plan et l’utilisation des mémoires tampons. | |
db_id |
oid | pg_database.oid | OID de la base de données dans laquelle l’instruction a été exécutée. |
query_id |
bigint | Code de hachage interne, calculé à partir de l’arborescence d’analyse de l’instruction. | |
plan_text |
varchar(10000) | Plan d’exécution de l’instruction donnée costs=false, buffers=false, and format=false. Sortie identique à celle produite par EXPLAIN. |
Functions
query_store.qs_reset
Cette fonction ignore toutes les statistiques collectées jusqu’à présent par le magasin des requêtes. Il ignore les statistiques pour les fenêtres de temps déjà fermées, qui sont déjà conservées sur des tables sur disque. Il ignore également les statistiques de la fenêtre de temps actuelle, qui existe uniquement en mémoire. Seuls les membres disposant du rôle administrateur de serveur (azure_pg_admin
) peuvent exécuter cette fonction.
query_store.staging_data_reset
Cette fonction supprime toutes les statistiques collectées en mémoire par le magasin des requêtes (c’est-à-dire les données en mémoire qui n’ont pas encore été transférées dans les tables sur disque qui assurent la persistance des données collectées pour le magasin des requêtes). Seuls les membres disposant du rôle administrateur de serveur (azure_pg_admin
) peuvent exécuter cette fonction.
Mode Lecture seule
Lorsqu’une instance de serveur flexible Azure Database pour PostgreSQL est en mode lecture seule, par exemple lorsque le paramètre default_transaction_read_only
est défini sur on
, ou si le mode lecture seule est automatiquement activé en raison d’une capacité de stockage atteinte, le magasin des requêtes ne capture aucune donnée.
L’activation du magasin des requêtes sur un serveur qui contient des réplicas en lecture n’active pas automatiquement le magasin des requêtes sur les réplicas en lecture. Même si vous l’activez sur l’un des réplicas en lecture, le magasin des requêtes n’enregistre pas les requêtes exécutées sur les réplicas en lecture, car ils fonctionnent en mode lecture seule jusqu’à ce que vous les promouviez en mode principal.