Skip to main content
Cette page fournit des recommandations pratiques pour choisir le bon layout de dictionnaire, comprendre quand les dictionnaires sont plus performants que les JOIN (et quand ils ne le sont pas), et surveiller l’utilisation des dictionnaires. Pour une introduction aux dictionnaires avec des exemples détaillés, consultez le guide principal des dictionnaires.

Quand utiliser des dictionnaires plutôt que des JOINs

Les dictionnaires sont particulièrement adaptés lorsqu’un côté d’un JOIN est une table de correspondance qui tient en mémoire. Avec un JOIN standard, ClickHouse construit une table de hachage à partir du côté droit avant de l’interroger avec le côté gauche — même si la plupart des lignes sont ensuite écartées par les filtres WHERE. Bien que les versions récentes (24.12+) appliquent les filtres avant les JOINs dans de nombreux cas, cela n’élimine pas toujours ce surcoût. Avec un dictionnaire, vous appelez dictGet directement, de sorte que les lookups ne s’effectuent que sur les lignes qui ont déjà passé le filtrage. Cependant, dictGet n’est pas toujours le bon choix. Si vous devez appeler dictGet sur un grand pourcentage des lignes d’une table — par exemple, dans une condition WHERE telle que dictGet('dict', 'elevation', id) > 1800 — il peut être préférable d’utiliser une colonne classique avec des index natifs. ClickHouse peut utiliser PREWHERE pour ignorer des granules sur une colonne classique, mais dictGet est évalué ligne par ligne sans prise en charge des index. En règle générale :
  • Utilisez des dictionnaires pour remplacer les JOINs sur de petites tables de dimension lorsque la clé de lookup est déjà disponible.
  • Utilisez des colonnes classiques et des index lorsque vous filtrez sur la valeur récupérée sur un grand nombre de lignes.

Choisir un layout

La clause LAYOUT contrôle la structure de données interne du dictionnaire. Tous les layouts disponibles sont documentés dans la référence des layouts. Lorsque vous choisissez un layout, suivez les recommandations suivantes :
  • flat — le layout le plus rapide (recherche simple par décalage dans un tableau), mais les clés doivent être de type UInt64 et sont limitées à 500 000 par défaut (max_array_size). Idéal pour des clés entières croissantes monotones dans des tables de petite ou moyenne taille. Les distributions de clés clairsemées (par exemple, des valeurs de clé 1 et 500 000) gaspillent de la mémoire, car le tableau est dimensionné en fonction de la plus grande clé. Si vous atteignez la limite des 500k, c’est généralement le signe qu’il faut passer à hashed_array.
  • hashed_array — le choix par défaut recommandé pour la plupart des cas d’usage. Stocke les attributs dans des tableaux, avec une table de hachage qui associe les clés aux indices des tableaux. Presque aussi rapide que hashed, mais plus économe en mémoire, surtout lorsqu’il y a beaucoup d’attributs.
  • hashed — stocke l’intégralité du dictionnaire dans une table de hachage. Peut être plus rapide que hashed_array lorsque vous avez très peu d’attributs, mais consomme davantage de mémoire à mesure que leur nombre augmente.
  • complex_key_hashed / complex_key_hashed_array — utilisez-les lorsque les clés ne peuvent pas être converties en UInt64 (par exemple, des clés String). Ils présentent les mêmes compromis de performance que leurs équivalents non complexes.
  • sparse_hashed — réduit l’utilisation de la mémoire au prix d’une consommation CPU plus élevée par rapport à hashed. C’est rarement le meilleur choix : il n’est réellement efficace que lorsque vous n’avez qu’un seul attribut. Dans la plupart des cas, hashed_array est plus adapté.
  • cache / ssd_cache — ne mettent en cache que les clés fréquemment consultées. Utile lorsque l’ensemble du dataset ne tient pas en mémoire, mais les recherches peuvent interroger la source en cas de cache miss. Non recommandé pour les charges de travail sensibles à la latence.
  • direct — interroge la source à chaque recherche, sans stockage en mémoire. À utiliser lorsque les données changent trop fréquemment pour être mises en cache ou lorsque le dictionnaire est trop volumineux pour tenir en mémoire.

Suivi de l’utilisation des dictionnaires

Suivez la consommation mémoire et l’état via la table system.dictionaries :
Colonnes clés :
  • bytes_allocated — mémoire consommée par le dictionnaire. Les dictionnaires stockent les données non compressées, donc cette valeur peut être nettement supérieure à la taille de la table compressée.
  • hit_rate et found_rate — utiles pour évaluer l’efficacité du layout cache.
  • last_exception — vérifiez ce point lorsqu’un dictionnaire ne parvient pas à se charger ou à s’actualiser.
Dernière modification le 3 juillet 2026