Dans cette page, nous utilisons indifféremment le terme “clé de tri” pour désigner la “clé primaire”. À strictement parler, ces deux notions diffèrent dans ClickHouse, mais dans le cadre de ce document, elles peuvent être utilisées de façon interchangeable, la clé de tri désignant les colonnes spécifiées dans le ORDER BY de la table.
Notez qu’une clé primaire ClickHouse fonctionne très différemment de ce que recouvre ce terme dans des bases de données OLTP comme Postgres.
Choisir une clé primaire efficace dans ClickHouse est essentiel pour les performances des requêtes et l’efficacité du stockage. ClickHouse organise les données en parties, chacune contenant son propre index primaire clairsemé. Cet index accélère considérablement les requêtes en réduisant le volume de données à analyser. De plus, comme la clé primaire détermine l’ordre physique des données sur le disque, elle influe directement sur l’efficacité de la compression. Des données ordonnées de manière optimale se compressent mieux, ce qui améliore encore les performances en réduisant les E/S.
- Lors du choix d’une clé de tri, privilégiez les colonnes fréquemment utilisées dans les filtres de requête (c.-à-d. la clause
WHERE), en particulier celles qui permettent d’exclure un grand nombre de lignes. - Les colonnes fortement corrélées avec d’autres données de la table sont également utiles, car un stockage contigu améliore les taux de compression et l’efficacité mémoire lors des opérations
GROUP BYetORDER BY.
Quelques règles simples peuvent aider à choisir une clé de tri. Les critères ci-dessous peuvent parfois entrer en conflit ; examinez-les donc dans cet ordre. Ce processus peut vous amener à identifier plusieurs clés, mais 4 à 5 suffisent généralement :
ImportantLes clés de tri doivent être définies lors de la création de la table et ne peuvent pas être ajoutées par la suite. Il est toutefois possible d’ajouter un tri supplémentaire à une table, avant ou après l’insertion des données, à l’aide d’une fonctionnalité appelée projections. Gardez à l’esprit que cela duplique les données. Plus de détails ici.
Exemple
posts_unordered suivante. Elle contient une ligne par post Stack Overflow.
Cette table n’a pas de clé primaire, comme l’indique ORDER BY tuple().
EXPLAIN indexes=1 confirme un parcours complet de la table dû à l’absence d’indexation.
posts_ordered, contenant les mêmes données, soit définie avec un ORDER BY de la forme (PostTypeId, toDate(CreationDate)), c’est-à-dire :
PostTypeId a une cardinalité de 8 et constitue donc le choix logique pour la première entrée de notre clé de tri. Comme un filtrage à la granularité de la date sera probablement suffisant (tout en restant bénéfique pour les filtres DateTime), nous utilisons toDate(CreationDate) comme 2e composant de notre clé. Cela produira également un index plus petit, car une date peut être représentée sur 16 bits, ce qui accélère le filtrage.
L’animation suivante montre comment un index primaire clairsemé optimisé est créé pour la table Posts de Stack Overflow. Au lieu d’indexer les lignes individuellement, l’index cible des blocs de lignes :
Si la même requête est répétée sur une table avec cette clé de tri :
EXPLAIN indexes=1.
Toutes les colonnes d’une table sont triées selon la valeur de la clé de tri spécifiée, qu’elles soient ou non incluses dans la clé elle-même. Par exemple, si
CreationDate est utilisée comme clé, l’ordre des valeurs dans toutes les autres colonnes correspondra à l’ordre des valeurs de la colonne CreationDate. Plusieurs clés de tri peuvent être spécifiées : l’ordre suivra alors la même sémantique qu’une clause ORDER BY dans une requête SELECT.