ClickHouse/docs/fr/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-layout.md

374 lines
13 KiB
Markdown
Raw Normal View History

2020-03-30 12:48:55 +00:00
---
machine_translated: true
2020-04-04 09:15:31 +00:00
machine_translated_rev: f865c9653f9df092694258e0ccdd733c339112f5
toc_priority: 41
toc_title: "Stockage des dictionnaires en m\xE9moire"
2020-03-30 12:48:55 +00:00
---
2020-04-04 09:15:31 +00:00
# Stockage Des Dictionnaires En Mémoire {#dicts-external-dicts-dict-layout}
2020-03-30 12:48:55 +00:00
Il existe une variété de façons de stocker les dictionnaires en mémoire.
Nous vous recommandons [plat](#flat), [haché](#dicts-external_dicts_dict_layout-hashed) et [complex\_key\_hashed](#complex-key-hashed). qui fournissent la vitesse de traitement optimale.
La mise en cache nest pas recommandée en raison de performances potentiellement médiocres et de difficultés à sélectionner les paramètres optimaux. En savoir plus dans la section “[cache](#cache)”.
2020-03-30 12:48:55 +00:00
Il existe plusieurs façons daméliorer les performances du dictionnaire:
2020-03-30 12:48:55 +00:00
- Appelez la fonction pour travailler avec le dictionnaire après `GROUP BY`.
- Marquer les attributs à extraire comme injectifs. Un attribut est appelé injectif si différentes valeurs dattribut correspondent à différentes clés. Alors, quand `GROUP BY` utilise une fonction qui récupère une valeur dattribut par la clé, cette fonction est automatiquement retirée de `GROUP BY`.
2020-03-30 12:48:55 +00:00
ClickHouse génère une exception pour les erreurs avec les dictionnaires. Des exemples derreurs:
2020-03-30 12:48:55 +00:00
- Le dictionnaire accessible na pas pu être chargé.
- Erreur de la requête dune `cached` dictionnaire.
2020-03-30 12:48:55 +00:00
Vous pouvez afficher la liste des dictionnaires externes et leurs statuts dans le `system.dictionaries` table.
La configuration ressemble à ceci:
``` xml
<yandex>
<dictionary>
...
<layout>
<layout_type>
<!-- layout settings -->
</layout_type>
</layout>
...
</dictionary>
</yandex>
```
2020-04-04 09:15:31 +00:00
Correspondant [DDL-requête](../../statements/create.md#create-dictionary-query):
2020-03-30 12:48:55 +00:00
``` sql
CREATE DICTIONARY (...)
...
LAYOUT(LAYOUT_TYPE(param value)) -- layout settings
...
```
2020-04-04 09:15:31 +00:00
## Façons De Stocker Des Dictionnaires En Mémoire {#ways-to-store-dictionaries-in-memory}
2020-03-30 12:48:55 +00:00
- [plat](#flat)
- [haché](#dicts-external_dicts_dict_layout-hashed)
- [sparse\_hashed](#dicts-external_dicts_dict_layout-sparse_hashed)
- [cache](#cache)
- [range\_hashed](#range-hashed)
- [complex\_key\_hashed](#complex-key-hashed)
- [complex\_key\_cache](#complex-key-cache)
- [ip\_trie](#ip-trie)
### plat {#flat}
Le dictionnaire est complètement stocké en mémoire sous la forme de tableaux plats. Combien de mémoire le dictionnaire utilise-t-il? Le montant est proportionnel à la taille de la plus grande clé (dans lespace).
2020-03-30 12:48:55 +00:00
La clé du dictionnaire a le `UInt64` type et la valeur est limitée à 500 000. Si une clé plus grande est découverte lors de la création du dictionnaire, ClickHouse lève une exception et ne crée pas le dictionnaire.
Tous les types de sources sont pris en charge. Lors de la mise à jour, les données (à partir dun fichier ou dune table) sont lues dans leur intégralité.
2020-03-30 12:48:55 +00:00
Cette méthode fournit les meilleures performances parmi toutes les méthodes disponibles de stockage du dictionnaire.
Exemple de Configuration:
``` xml
<layout>
<flat />
</layout>
```
ou
``` sql
LAYOUT(FLAT())
```
### haché {#dicts-external_dicts_dict_layout-hashed}
Le dictionnaire est entièrement stockée en mémoire sous la forme dune table de hachage. Le dictionnaire peut contenir nimporte quel nombre déléments avec tous les identificateurs Dans la pratique, le nombre de clés peut atteindre des dizaines de millions darticles.
2020-03-30 12:48:55 +00:00
Tous les types de sources sont pris en charge. Lors de la mise à jour, les données (à partir dun fichier ou dune table) sont lues dans leur intégralité.
2020-03-30 12:48:55 +00:00
Exemple de Configuration:
``` xml
<layout>
<hashed />
</layout>
```
ou
``` sql
LAYOUT(HASHED())
```
### sparse\_hashed {#dicts-external_dicts_dict_layout-sparse_hashed}
Semblable à `hashed`, mais utilise moins de mémoire en faveur de plus Dutilisation du processeur.
2020-03-30 12:48:55 +00:00
Exemple de Configuration:
``` xml
<layout>
<sparse_hashed />
</layout>
```
``` sql
LAYOUT(SPARSE_HASHED())
```
### complex\_key\_hashed {#complex-key-hashed}
Ce type de stockage est pour une utilisation avec composite [touches](external-dicts-dict-structure.md). Semblable à `hashed`.
2020-03-30 12:48:55 +00:00
Exemple de Configuration:
``` xml
<layout>
<complex_key_hashed />
</layout>
```
``` sql
LAYOUT(COMPLEX_KEY_HASHED())
```
### range\_hashed {#range-hashed}
Le dictionnaire est stocké en mémoire sous la forme dune table de hachage avec un tableau ordonné de gammes et leurs valeurs correspondantes.
2020-03-30 12:48:55 +00:00
Cette méthode de stockage fonctionne de la même manière que hachée et permet dutiliser des plages de date / heure (Type numérique arbitraire) en plus de la clé.
2020-03-30 12:48:55 +00:00
Exemple: Le tableau contient des réductions pour chaque annonceur dans le format:
``` text
2020-04-04 09:15:31 +00:00
+---------|-------------|-------------|------+
2020-03-30 12:48:55 +00:00
| advertiser id | discount start date | discount end date | amount |
+===============+=====================+===================+========+
| 123 | 2015-01-01 | 2015-01-15 | 0.15 |
2020-04-04 09:15:31 +00:00
+---------|-------------|-------------|------+
2020-03-30 12:48:55 +00:00
| 123 | 2015-01-16 | 2015-01-31 | 0.25 |
2020-04-04 09:15:31 +00:00
+---------|-------------|-------------|------+
2020-03-30 12:48:55 +00:00
| 456 | 2015-01-01 | 2015-01-15 | 0.05 |
2020-04-04 09:15:31 +00:00
+---------|-------------|-------------|------+
2020-03-30 12:48:55 +00:00
```
Pour utiliser un échantillon pour les plages de dates, définissez `range_min` et `range_max` éléments dans le [structure](external-dicts-dict-structure.md). Ces éléments doivent contenir des éléments `name` et`type` (si `type` nest pas spécifié, le type par défaut sera utilisé-Date). `type` peut être nimporte quel type numérique (Date / DateTime / UInt64 / Int32 / autres).
2020-03-30 12:48:55 +00:00
Exemple:
``` xml
<structure>
<id>
<name>Id</name>
</id>
<range_min>
<name>first</name>
<type>Date</type>
</range_min>
<range_max>
<name>last</name>
<type>Date</type>
</range_max>
...
```
ou
``` sql
CREATE DICTIONARY somedict (
id UInt64,
first Date,
last Date
)
PRIMARY KEY id
LAYOUT(RANGE_HASHED())
RANGE(MIN first MAX last)
```
Pour travailler avec ces dictionnaires, vous devez passer un argument supplémentaire à l `dictGetT` fonction, pour laquelle une plage est sélectionnée:
2020-03-30 12:48:55 +00:00
``` sql
dictGetT('dict_name', 'attr_name', id, date)
```
Cette fonction retourne la valeur pour l `id`s et la plage de dates qui inclut la date passée.
2020-03-30 12:48:55 +00:00
Détails de lalgorithme:
2020-03-30 12:48:55 +00:00
- Si l `id` est introuvable ou une plage nest pas trouvé pour l `id` il retourne la valeur par défaut pour le dictionnaire.
- Sil y a des plages qui se chevauchent, vous pouvez en utiliser.
2020-03-30 12:48:55 +00:00
- Si le délimiteur est `NULL` ou une date non valide (telle que 1900-01-01 ou 2039-01-01), la plage est laissée ouverte. La gamme peut être ouverte des deux côtés.
Exemple de Configuration:
``` xml
<yandex>
<dictionary>
...
<layout>
<range_hashed />
</layout>
<structure>
<id>
<name>Abcdef</name>
</id>
<range_min>
<name>StartTimeStamp</name>
<type>UInt64</type>
</range_min>
<range_max>
<name>EndTimeStamp</name>
<type>UInt64</type>
</range_max>
<attribute>
<name>XXXType</name>
<type>String</type>
<null_value />
</attribute>
</structure>
</dictionary>
</yandex>
```
ou
``` sql
CREATE DICTIONARY somedict(
Abcdef UInt64,
StartTimeStamp UInt64,
EndTimeStamp UInt64,
XXXType String DEFAULT ''
)
PRIMARY KEY Abcdef
RANGE(MIN StartTimeStamp MAX EndTimeStamp)
```
### cache {#cache}
Le dictionnaire est stocké dans un cache qui a un nombre fixe de cellules. Ces cellules contiennent des éléments fréquemment utilisés.
Lors de la recherche dun dictionnaire, le cache est recherché en premier. Pour chaque bloc de données, toutes les clés qui ne sont pas trouvées dans le cache ou qui sont obsolètes sont demandées à la source en utilisant `SELECT attrs... FROM db.table WHERE id IN (k1, k2, ...)`. Les données reçues sont ensuite écrites dans le cache.
2020-03-30 12:48:55 +00:00
Pour les dictionnaires de cache, lexpiration [vie](external-dicts-dict-lifetime.md) des données dans le cache peuvent être définies. Si plus de temps que `lifetime` passé depuis le chargement des données dans une cellule, la valeur de la cellule nest pas utilisée et elle est demandée à nouveau la prochaine fois quelle doit être utilisée.
Cest la moins efficace de toutes les façons de stocker les dictionnaires. La vitesse du cache dépend fortement des paramètres corrects et que le scénario dutilisation. Un dictionnaire de type de cache fonctionne bien uniquement lorsque les taux de réussite sont suffisamment élevés (recommandé 99% et plus). Vous pouvez afficher le taux de réussite moyen dans le `system.dictionaries` table.
2020-03-30 12:48:55 +00:00
Pour améliorer les performances du cache, utilisez une sous-requête avec `LIMIT`, et appelez la fonction avec le dictionnaire en externe.
Soutenu [source](external-dicts-dict-sources.md): MySQL, ClickHouse, exécutable, HTTP.
2020-03-30 12:48:55 +00:00
Exemple de paramètres:
``` xml
<layout>
<cache>
<!-- The size of the cache, in number of cells. Rounded up to a power of two. -->
<size_in_cells>1000000000</size_in_cells>
</cache>
</layout>
```
ou
``` sql
LAYOUT(CACHE(SIZE_IN_CELLS 1000000000))
```
Définissez une taille de cache suffisamment grande. Vous devez expérimenter pour sélectionner le nombre de cellules:
1. Définissez une valeur.
2. Exécutez les requêtes jusquà ce que le cache soit complètement plein.
2020-03-30 12:48:55 +00:00
3. Évaluer la consommation de mémoire en utilisant le `system.dictionaries` table.
4. Augmentez ou diminuez le nombre de cellules jusquà ce que la consommation de mémoire requise soit atteinte.
2020-03-30 12:48:55 +00:00
!!! warning "Avertissement"
Nutilisez pas ClickHouse comme source, car le traitement des requêtes avec des lectures aléatoires est lent.
2020-03-30 12:48:55 +00:00
### complex\_key\_cache {#complex-key-cache}
Ce type de stockage est pour une utilisation avec composite [touches](external-dicts-dict-structure.md). Semblable à `cache`.
2020-03-30 12:48:55 +00:00
### ip\_trie {#ip-trie}
Ce type de stockage permet de mapper des préfixes de réseau (adresses IP) à des métadonnées telles que ASN.
Exemple: la table contient les préfixes de réseau et leur correspondant en tant que numéro et Code de pays:
``` text
2020-04-04 09:15:31 +00:00
+-----------|-----|------+
2020-03-30 12:48:55 +00:00
| prefix | asn | cca2 |
+=================+=======+========+
| 202.79.32.0/20 | 17501 | NP |
2020-04-04 09:15:31 +00:00
+-----------|-----|------+
2020-03-30 12:48:55 +00:00
| 2620:0:870::/48 | 3856 | US |
2020-04-04 09:15:31 +00:00
+-----------|-----|------+
2020-03-30 12:48:55 +00:00
| 2a02:6b8:1::/48 | 13238 | RU |
2020-04-04 09:15:31 +00:00
+-----------|-----|------+
2020-03-30 12:48:55 +00:00
| 2001:db8::/32 | 65536 | ZZ |
2020-04-04 09:15:31 +00:00
+-----------|-----|------+
2020-03-30 12:48:55 +00:00
```
Lorsque vous utilisez ce type de mise en page, la structure doit avoir une clé composite.
Exemple:
``` xml
<structure>
<key>
<attribute>
<name>prefix</name>
<type>String</type>
</attribute>
</key>
<attribute>
<name>asn</name>
<type>UInt32</type>
<null_value />
</attribute>
<attribute>
<name>cca2</name>
<type>String</type>
<null_value>??</null_value>
</attribute>
...
```
ou
``` sql
CREATE DICTIONARY somedict (
prefix String,
asn UInt32,
cca2 String DEFAULT '??'
)
PRIMARY KEY prefix
```
La clé ne doit avoir quun seul attribut de type chaîne contenant un préfixe IP autorisé. Les autres types ne sont pas encore pris en charge.
2020-03-30 12:48:55 +00:00
Pour les requêtes, vous devez utiliser les mêmes fonctions (`dictGetT` avec un n-uplet) comme pour les dictionnaires avec des clés composites:
``` sql
dictGetT('dict_name', 'attr_name', tuple(ip))
```
La fonction prend soit `UInt32` pour IPv4, ou `FixedString(16)` pour IPv6:
``` sql
dictGetString('prefix', 'asn', tuple(IPv6StringToNum('2001:db8::1')))
```
Les autres types ne sont pas encore pris en charge. La fonction renvoie lattribut du préfixe correspondant à cette adresse IP. Sil y a chevauchement des préfixes, le plus spécifique est retourné.
2020-03-30 12:48:55 +00:00
Les données sont stockées dans une `trie`. Il doit complètement sintégrer dans la RAM.
2020-03-30 12:48:55 +00:00
[Article Original](https://clickhouse.tech/docs/en/query_language/dicts/external_dicts_dict_layout/) <!--hide-->