Skip to main content
Le diagnostic d’une requête lente commence par l’analyse de son historique. Ce guide explique comment utiliser system.query_log pour identifier des schémas récurrents de requêtes lentes, choisir une exécution représentative et examiner son utilisation des ressources. Vous utiliserez ensuite EXPLAIN pour examiner le plan de requête et formuler une hypothèse sur le goulot d’étranglement avant de modifier la requête ou le schéma.

Avant de commencer

Les exemples de ce guide utilisent la table nyc_taxi.trips_small_inferred. Pour les exécuter tels quels, créez et chargez la table si ce n’est pas déjà fait :
Le fichier Parquet source fait environ 5,8 Go. Son chargement peut prendre plusieurs minutes, selon votre réseau et les ressources disponibles.
Pour reproduire les résultats du journal des requêtes de ce guide, exécutez chacune des trois requêtes de charge de travail d’exemple au moins deux fois après avoir chargé le jeu de données. Videz ensuite le journal des requêtes afin que les exécutions terminées soient disponibles pour les exemples ci-dessous :
Si vous ne pouvez pas exécuter SYSTEM FLUSH LOGS, attendez que le journal des requêtes soit automatiquement écrit sur le stockage, puis réessayez la première recherche. Lorsque vous analysez votre propre charge de travail, assurez-vous que system.query_log contient des exécutions terminées couvrant l’intervalle de temps que vous souhaitez examiner.

Fonctionnement

Par défaut, ClickHouse enregistre des informations sur les requêtes terminées dans la table system.query_log. Chaque enregistrement peut inclure la durée de la requête, le nombre de lignes lues, l’utilisation du CPU et de la mémoire, ainsi que l’activité du cache du système de fichiers. Ces mesures vous aident à identifier les modèles de requêtes lentes et à comprendre comment elles utilisent les ressources. Après avoir sélectionné une exécution représentative, vous pouvez examiner son plan d’exécution afin de déterminer à quel niveau la requête pourrait passer du temps. Dans un cluster, les données du journal des requêtes restent locales à chaque nœud. Les exemples de ce guide utilisent clusterAllReplicas pour interroger chaque réplique et merge pour inclure la table system.query_log actuelle ainsi que les tables query_log_N versionnées conservées après des modifications du schéma des tables système. Chaque exemple du journal des requêtes comprend des onglets pour les déploiements en cluster et sur un nœud unique. ClickHouse Cloud fournit le cluster default utilisé dans les exemples de cluster. Dans un déploiement autogéré, remplacez default par un cluster répertorié dans system.clusters.
Les exemples définissent skip_unavailable_shards afin qu’une réplique temporairement indisponible n’entraîne pas l’échec de la requête de diagnostic. Cela est particulièrement utile lors de la mise à l’échelle automatique. Les enregistrements d’une réplique ignorée ne sont pas inclus ; les résultats peuvent donc être incomplets.

Diagnostiquer une requête lente

À partir des exécutions terminées consignées dans le journal des requêtes, suivez ces trois étapes dans l’ordre. Vous identifierez un schéma récurrent de requête lente, choisirez une exécution représentative et examinerez le plan d’exécution de la requête.
1

Identifier les requêtes candidates

Commencez par regrouper les requêtes initiales terminées par normalized_query_hash. Cela permet de distinguer les modèles de requêtes récurrents des exécutions lentes isolées. La requête suivante classe les modèles par durée médiane et fournit un exemple de requête pour chaque modèle :
Utilisez executions pour distinguer un workload récurrent de queries isolées. Un pattern présentant une durée médiane élevée, des exécutions fréquentes ou une consommation de ressources importante constitue un candidat plus pertinent pour une investigation qu’une unique exécution lente.Pour dresser un rapide inventaire, la requête suivante liste l’exécution terminée la plus lente pour un maximum de cinq query patterns distincts sur le jeu de données des taxis de NYC. Elle exclut les statements de chargement du jeu de données ainsi que les exécutions répétées d’un même pattern. À l’étape suivante, vous restreindrez le query history aux exécutions correspondant au normalized_query_hash sélectionné ci-dessus.
Le champ query_duration_ms contient la durée de la requête en millisecondes. Dans ces résultats, la requête la plus longue a duré 2 967 ms.Vous pouvez également identifier les requêtes candidates en fonction de l’utilisation des ressources plutôt que de la durée des requêtes :
Cette requête classe les requêtes récentes par utilisation de la mémoire et indique leur utilisation du CPU. Les résultats varient selon la charge de travail et le déploiement :
2

Choisissez l’exécution représentative d’une requête

Une seule exécution lente peut être une valeur aberrante due à une requête ponctuelle ou à une charge système temporaire. Avant d’inspecter le plan de requête, examinez plusieurs exécutions terminées présentant le même normalized_query_hash, identique pour les requêtes qui ne diffèrent que par leurs valeurs littérales. Choisissez une exécution représentative de la durée et de l’utilisation habituelles des ressources pour ce modèle.Remplacez la valeur affectée à selected_hash par le normalized_query_hash du modèle que vous souhaitez examiner :
  1. Recherchez les exécutions présentant des valeurs read_rows et read_bytes similaires.
  2. Comparez query_duration_ms et memory_usage pour ces exécutions.
  3. Sélectionnez le query_id dont le query_duration_ms est le plus proche de la médiane.
Les résultats historiques du journal de requêtes peuvent varier en fonction de l’état du cache et de la charge système. Utilisez-les donc pour choisir une requête à examiner, et non pour comparer des modifications d’optimisation. Si le journal de requêtes ne contient pas suffisamment d’exécutions terminées, exécutez la requête plusieurs fois dans des conditions similaires. Le guide suivant, Isoler les goulots d’étranglement des requêtes, explique comment recueillir des mesures contrôlées afin de comparer les modifications.
Les exemples de résultats du journal de requêtes montrent que chaque candidat a lu environ 329,04 millions de lignes. Pour référence, confirmez le nombre de lignes de la table d’exemple :
La table contient 329,04 millions de lignes, soit approximativement le même nombre que celui indiqué dans read_rows pour chaque candidat. Cela suggère que les requêtes ont parcouru la majeure partie, voire la totalité, de la table, mais n’indique pas pourquoi ces lignes ont été lues ni si ce volume est approprié pour la requête. Examinez ensuite le plan de requête pour voir comment ClickHouse a sélectionné et traité les données.
3

Inspectez le plan d’exécution

Après avoir choisi une exécution représentative, utilisez EXPLAIN pour examiner comment ClickHouse planifie la requête sans l’exécuter. La sortie indique les opérations que ClickHouse prévoit d’effectuer et la façon dont les données circulent entre elles, apportant davantage de contexte aux mesures du journal des requêtes.Pour une présentation détaillée des formats de sortie disponibles, consultez Comprendre l’exécution des requêtes avec l’analyseur. Dans cet exemple, EXPLAIN montre comment ClickHouse prévoit de lire et de filtrer les données, ainsi que s’il peut en ignorer une partie.La sortie se présente sous la forme d’un arbre d’opérations qui montre comment ClickHouse prévoit de lire, filtrer et traiter les données. Les opérations enfants apparaissent sous leurs opérations parentes. Commencez par l’opération de lecture la plus profonde, puis remontez le plan pour voir comment ClickHouse transforme les données en résultat final.Pour cet exemple, examinez la requête de calcul de vitesse dans les résultats du journal des requêtes :
La sortie comprend les opérations suivantes. Certains détails, comme le nombre de parts et de granules, dépendent du mode de stockage des données :
De bas en haut, le plan se rapporte à la requête comme suit :
  1. ReadFromMergeTree lit la table nyc_taxi.trips_small_inferred. L’absence de section Indexes, associée au fait que read_rows correspond au nombre de lignes de la table, montre que ClickHouse lit l’intégralité de la table.
  2. Filter affiche l’expression développée pour speed_mph > 30. Pour chaque ligne lue, ClickHouse calcule la durée et la vitesse du trajet, puis ne conserve que les lignes dont la vitesse dépasse 30 miles par heure.
  3. Aggregating calcule les quantiles à partir des valeurs filtrées de trip_distance.
Ce plan met en évidence trois sources de travail à tester : la lecture de toutes les lignes, le calcul de speed_mph lors du filtrage et le calcul des quantiles.

Prochaines étapes

Ensuite, consultez Isoler les goulots d’étranglement des requêtes pour apprendre à tester, dans des conditions contrôlées, les sources de charge suspectées. Ce guide compare des formes de requêtes de plus en plus simples afin d’identifier les opérations qui nécessitent une analyse plus approfondie.
Dernière modification le 28 août 2026