Skip to main content
Après avoir optimisé le stockage, l’étape suivante consiste à améliorer les performances des requêtes. Cette section présente deux techniques clés : l’optimisation des clés ORDER BY et l’utilisation de vues matérialisées. Nous verrons comment ces approches peuvent ramener le temps d’exécution des requêtes de quelques secondes à quelques millisecondes.

Optimiser les clés ORDER BY

Avant de tenter d’autres optimisations, vous devriez optimiser les clés de tri afin que ClickHouse produise les résultats les plus rapides possible. Le choix de la bonne clé dépend en grande partie des requêtes que vous allez exécuter. Supposons que la plupart de nos requêtes filtrent sur les colonnes project et subproject. Dans ce cas, il est judicieux de les ajouter à la clé de tri, ainsi que la colonne time, puisque nos requêtes filtrent aussi sur le temps. Créons une autre version de la table avec les mêmes types de colonnes que wikistat, mais triée selon (project, subproject, time).
Comparons maintenant plusieurs requêtes pour voir à quel point notre expression de clé de tri est essentielle aux performances. Notez que nous n’avons pas appliqué les optimisations précédentes sur les types de données et les codecs ; les écarts de performances entre les requêtes tiennent donc uniquement à l’ordre de tri.
Requête(time)(project, subproject, time)
2.381 sec1.660 sec
2.148 sec0.058 sec
2.192 sec0.012 sec
2.968 sec0.010 sec

Vues matérialisées

Une autre possibilité consiste à utiliser des vues matérialisées pour agréger et stocker les résultats des requêtes les plus fréquentes. On peut interroger ces résultats plutôt que la table d’origine. Supposons que la requête suivante soit exécutée assez souvent dans notre cas :

Créer une vue matérialisée

Vous pouvez créer la vue matérialisée suivante :

Alimentation rétroactive de la table de destination

Cette table de destination ne sera alimentée que lorsque de nouveaux enregistrements seront insérés dans la table wikistat ; nous devons donc effectuer une alimentation rétroactive. Le moyen le plus simple de procéder consiste à utiliser une instruction INSERT INTO SELECT pour insérer directement dans la table cible de la vue matérialisée en utilisant la requête SELECT de la vue (transformation) :
Selon la cardinalité du jeu de données brut (nous avons 1 milliard de lignes !), cette approche peut être gourmande en mémoire. Vous pouvez aussi utiliser une variante qui consomme très peu de mémoire :
  • Créer une table temporaire avec un Null table engine
  • Connecter une copie de la vue matérialisée habituellement utilisée à cette table temporaire
  • Utiliser une requête INSERT INTO SELECT pour copier toutes les données du jeu de données brut dans cette table temporaire
  • Supprimer la table temporaire et la vue matérialisée temporaire.
Avec cette approche, les lignes du jeu de données brut sont copiées bloc par bloc dans la table temporaire (qui ne stocke aucune de ces lignes) et, pour chaque bloc de lignes, un état partiel est calculé puis écrit dans la table cible, où ces états sont fusionnés de manière incrémentielle en arrière-plan.
Ensuite, nous allons créer une vue matérialisée pour lire à partir de wikistat_backfill et écrire dans wikistat_top
Et enfin, nous allons alimenter wikistat_backfill à partir de la table initiale wikistat :
Une fois la requête terminée, nous pouvons supprimer la table de chargement rétroactif et la vue matérialisée :
Nous pouvons maintenant interroger la vue matérialisée plutôt que la table d’origine :
Le gain de performances est spectaculaire. Auparavant, il fallait un peu plus de 2 secondes pour calculer la réponse à cette requête, et maintenant cela ne prend plus que 4 millisecondes.
Dernière modification le 3 juillet 2026