Que sont les partitions de table dans ClickHouse ?
Les partitions regroupent les parties de données d’une table de la famille de moteurs MergeTree en unités logiques structurées. Il s’agit d’une manière d’organiser les données qui a un sens sur le plan conceptuel et repose sur des critères précis, comme des intervalles de temps, des catégories ou d’autres attributs clés. Ces unités logiques facilitent la gestion, l’interrogation et l’optimisation des données.
PARTITION BY
PARTITION BY toStartOfMonth(date), qui organise les parties de table de la table en fonction des mois de vente des biens immobiliers :
Structure sur disque
Le serveur ClickHouse commence par répartir les 4 lignes de l’exemple d’insert illustré dans le diagramme ci-dessus en fonction de leur valeur de clé de partition
toStartOfMonth(date).
Ensuite, pour chaque partition identifiée, les lignes sont traitées comme d’habitude en suivant plusieurs étapes séquentielles (① Tri, ② Découpage en colonnes, ③ Compression, ④ Écriture sur disque).
Notez que lorsque le partitionnement est activé, ClickHouse crée automatiquement des index MinMax pour chaque partie de données. Il s’agit simplement de fichiers, un pour chaque colonne de la table utilisée dans l’expression de clé de partition, qui contiennent les valeurs minimale et maximale de cette colonne dans la partie de données.
Fusions par partition
Comme le montre le schéma ci-dessus, les parties appartenant à des partitions différentes ne sont jamais fusionnées. Si vous choisissez une clé de partition à cardinalité élevée, les parties réparties sur des milliers de partitions ne pourront jamais être candidates à une fusion, ce qui finit par dépasser les limites préconfigurées et provoquer la redoutable erreur
Too many parts. La solution est simple : choisissez une clé de partition pertinente avec une cardinalité inférieure à 1000..10000.
Surveillance des partitions
_partition_value :
Autrement, ClickHouse suit toutes les parts et partitions de toutes les tables dans la table système system.parts, et la requête suivante renvoie pour notre table d’exemple ci-dessus la liste de toutes les partitions, ainsi que le nombre actuel de parts actives et le total des lignes dans ces parts pour chaque partition :
À quoi servent les partitions de table ?
Gestion des données
toStartOfMonth(date), des partitions entières (des ensembles de parties de table) qui remplissent la condition TTL seront supprimées, ce qui rend l’opération de nettoyage plus efficace, sans qu’il soit nécessaire de réécrire les parties.
De même, au lieu de supprimer les anciennes données, celles-ci peuvent être déplacées automatiquement et efficacement vers un niveau de stockage plus économique :
Optimisation des requêtes
date) utilisée dans la clé de partitionnement de la table et sur une colonne (town) utilisée dans la clé primaire de la table (date ne faisant pas partie de la clé primaire).
ClickHouse traite cette requête en appliquant une série de techniques d’exclusion pour éviter d’évaluer des données non pertinentes :
① élagage des partitions : les index MinMax servent à ignorer des partitions entières (ensembles de parts) qui, logiquement, ne peuvent pas correspondre au filter de la requête sur les colonnes utilisées dans la clé de partitionnement de la table. ② élagage des granules : pour les data parts restantes après l’étape ①, leur index primaire sert à ignorer toutes les granules (blocs de rows) qui, logiquement, ne peuvent pas correspondre au filter de la requête sur les colonnes utilisées dans la clé primaire de la table. Nous pouvons observer ces étapes d’exclusion des données en inspectant le plan d’exécution physique de notre requête d’exemple ci-dessus via une clause EXPLAIN :
date pour identifier 11 des 3257 granules existantes (blocs de lignes) stockées dans 1 des 436 parties de données actives existantes, qui contiennent des lignes correspondant au filtre date de la requête.
② Élagage des granules : les lignes 19 à 24 de la sortie EXPLAIN ci-dessus indiquent que ClickHouse utilise ensuite l’index primaire (créé sur le champ town) de la partie de données identifiée à l’étape ① pour réduire encore le nombre de granules (qui contiennent des lignes susceptibles de correspondre aussi au filtre town de la requête) de 11 à 1. Cela se reflète également dans la sortie de clickhouse-client que nous avons affichée plus haut pour la requête exécutée :
Le partitionnement est avant tout une fonctionnalité de gestion des données
uk_price_paid_simple_partitioned comporte plus de 600 partitions, et donc 600 306 parties de données actives. En revanche, pour notre table non partitionnée uk_price_paid_simple, toutes les parties de données initiales ont pu être fusionnées en une seule partie active grâce aux fusions en arrière-plan.
Lorsque nous examinons le plan physique d’exécution de la requête avec une clause EXPLAIN pour notre requête d’exemple ci-dessus, sans le filtre de partition, sur la table partitionnée, nous pouvons voir aux lignes 19 et 20 de la sortie ci-dessous que ClickHouse a identifié 671 des 3257 granules existantes (blocs de lignes), réparties sur 431 des 436 parties de données actives existantes, comme pouvant potentiellement contenir des lignes correspondant au filtre de la requête, et qui seront donc analysées et traitées par le moteur de requête :