Passer au contenu principal

Limite de mémoire dépassée pour la requête

Pour un nouvel utilisateur, ClickHouse peut souvent sembler magique : chaque requête est extrêmement rapide, même sur les plus gros ensembles de données et les requêtes les plus ambitieuses. Inévitablement, cependant, l’utilisation en conditions réelles met aussi les limites de ClickHouse à l’épreuve. Les requêtes qui dépassent la limite de mémoire peuvent avoir plusieurs causes. Le plus souvent, nous observons de grosses jointures ou des agrégations sur des champs à forte cardinalité. Si les performances sont critiques et que ces requêtes sont nécessaires, nous recommandons souvent aux utilisateurs de simplement monter en capacité — ce que ClickHouse Cloud fait automatiquement et sans effort afin de garantir que vos requêtes restent réactives. Nous comprenons toutefois que, dans les environnements self-managed, cela n’est pas toujours simple, et que des performances optimales ne sont pas forcément nécessaires. Dans ce cas, les utilisateurs disposent de plusieurs options.

Agrégations

Pour les scénarios d’agrégation ou de tri gourmands en mémoire, les utilisateurs peuvent utiliser respectivement les paramètres max_bytes_before_external_group_by et max_bytes_before_external_sort. Le premier est traité en détail ici. En résumé, cela garantit que toute agrégation peut être déportée sur disque si un seuil de mémoire est dépassé. Cela aura inévitablement un impact sur les performances des requêtes, mais contribuera à éviter que les requêtes ne provoquent une erreur d’OOM. Le second paramètre de tri aide à résoudre des problèmes similaires liés aux tris gourmands en mémoire. Cela peut être particulièrement important dans des environnements distribués où un nœud coordinateur reçoit des réponses triées de shards enfants. Dans ce cas, le serveur coordinateur peut être amené à trier un jeu de données plus volumineux que la mémoire dont il dispose. Avec max_bytes_before_external_sort, le tri peut être autorisé à déborder sur le disque. Ce paramètre est également utile dans les cas où l’utilisateur a un ORDER BY après un GROUP BY avec un LIMIT, en particulier lorsque la requête est distribuée.

Jointures

Pour les jointures, les utilisateurs peuvent sélectionner différents algorithmes JOIN, ce qui peut aider à réduire la mémoire nécessaire. Par défaut, les jointures utilisent le hash join, qui offre la meilleure couverture fonctionnelle et souvent les meilleures performances. Cet algorithme charge en mémoire la table située à droite du JOIN dans une table de hachage, sur laquelle la table de gauche est ensuite évaluée. Pour minimiser l’utilisation de la mémoire, les utilisateurs doivent donc placer la plus petite table à droite. Cette approche présente toutefois encore des limites lorsque la mémoire est contrainte. Dans ce cas, la jointure partial_merge peut être activée via le paramètre join_algorithm. Cette variante de l’algorithme de tri-fusion commence par trier la table de droite en blocs et à créer un index min-max pour ceux-ci. Elle trie ensuite des parties de la table de gauche selon la clé de jointure, puis les joint à la table de droite. L’index min-max est utilisé pour ignorer les blocs inutiles de la table de droite. Cette méthode consomme moins de mémoire, au détriment des performances. En poussant ce concept plus loin, l’algorithme full_sorting_merge permet d’exécuter un JOIN lorsque la partie droite est très volumineuse, ne tient pas en mémoire et que les lookup sont impossibles, par exemple dans le cas d’une sous-requête complexe. Dans ce cas, les parties droite et gauche sont toutes deux triées sur disque si elles ne tiennent pas en mémoire, ce qui permet de joindre de grandes tables. Depuis la version 20.3, ClickHouse prend en charge la valeur auto pour le paramètre join_algorithm. Cela indique à ClickHouse d’appliquer une approche adaptative des jointures, dans laquelle l’algorithme de hash join est privilégié jusqu’à ce que les limites de mémoire soient dépassées, auquel cas l’algorithme partial_merge est tenté. Enfin, concernant les jointures, nous encourageons les lecteurs à bien comprendre le comportement des jointures distribuées et la manière de minimiser leur consommation de mémoire. Vous trouverez plus d’informations ici.
Dernière modification le 29 juin 2026