> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-postgresql-tls-support.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Bonnes pratiques pour les dictionnaires

> Recommandations pour choisir les layouts de dictionnaire, savoir quand utiliser des dictionnaires plutôt que des JOIN, et surveiller l’utilisation des dictionnaires.

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](/fr/concepts/features/dictionaries/index).

<div id="when-to-use-dictionaries-vs-joins">
  ## Quand utiliser des dictionnaires plutôt que des JOINs
</div>

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.

<div id="choosing-a-layout">
  ## Choisir un layout
</div>

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](/fr/reference/statements/create/dictionary/layouts/overview#storing-dictionaries-in-memory).

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.

<div id="monitoring-dictionary-usage">
  ## Suivi de l’utilisation des dictionnaires
</div>

Suivez la consommation mémoire et l’état via la table [`system.dictionaries`](/fr/reference/system-tables/dictionaries) :

```sql theme={null}
SELECT
    name,
    status,
    element_count,
    formatReadableSize(bytes_allocated) AS size,
    query_count,
    hit_rate,
    found_rate,
    last_exception
FROM 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.
