Skip to main content
Les mises à jour légères sont actuellement en bêta. Si vous rencontrez des problèmes, veuillez ouvrir une issue dans le dépôt ClickHouse.
L’instruction UPDATE légère met à jour les lignes d’une table [db.]table qui correspondent à l’expression filter_expr. Elle est appelée “lightweight update” pour la distinguer de la requête ALTER TABLE ... UPDATE, qui est un processus lourd réécrivant des colonnes entières dans des parties de données. Elle n’est disponible que pour la famille de moteurs de table MergeTree.
Le filter_expr doit être de type UInt8. Cette requête met à jour les valeurs des colonnes spécifiées avec celles des expressions correspondantes, dans les lignes pour lesquelles filter_expr a une valeur non nulle. Les valeurs sont converties vers le type de la colonne à l’aide de l’opérateur CAST. La mise à jour des colonnes utilisées pour calculer la clé primaire ou les clés de partitionnement n’est pas prise en charge.

Exemples

Les mises à jour légères ne mettent pas les données à jour immédiatement

La fonctionnalité UPDATE légère est implémentée à l’aide de patch parts — un type spécial de partie de données qui contient uniquement les colonnes et les lignes mises à jour. Une opération UPDATE légère crée des patch parts, mais ne modifie pas immédiatement et physiquement les données d’origine en stockage. Le processus de mise à jour est similaire à une requête INSERT ... SELECT ..., mais la requête UPDATE attend que la création de la patch part soit terminée avant de se terminer. Les valeurs mises à jour sont :
  • Immédiatement visibles dans les requêtes SELECT via l’application des patches
  • Physiquement matérialisées uniquement lors des fusions et mutations ultérieures
  • Automatiquement nettoyées une fois que toutes les parties actives ont leurs patches matérialisés

Exigences pour les mises à jour légères

Les mises à jour légères sont prises en charge par les moteurs MergeTree, ReplacingMergeTree, CollapsingMergeTree, VersionedCollapsingMergeTree, ainsi que par leurs versions Replicated et Shared. Pour utiliser les mises à jour légères, la matérialisation des colonnes _block_number et _block_offset doit être activée à l’aide des paramètres de table enable_block_number_column et enable_block_offset_column.

Suppressions légères

Une requête lightweight DELETE peut être exécutée sous forme de lightweight UPDATE plutôt que comme une mutation ALTER UPDATE. L’implémentation de lightweight DELETE est contrôlée par le paramètre lightweight_delete_mode.

Considérations relatives aux performances

Avantages des mises à jour légères :
  • La latence de la mise à jour est comparable à celle de la requête INSERT ... SELECT ...
  • Seules les colonnes et les valeurs mises à jour sont écrites, et non des colonnes entières dans les parties de données
  • Il n’est pas nécessaire d’attendre la fin des fusions/mutations en cours ; la latence d’une mise à jour est donc prévisible
  • L’exécution parallèle des mises à jour légères est possible
Impacts potentiels sur les performances :
  • Ajoute une surcharge aux requêtes SELECT qui doivent appliquer des patchs
  • Les index de saut de données ne sont pas utilisés pour les colonnes des parties de données auxquelles des patchs doivent être appliqués. Les projections ne sont pas utilisées s’il existe des patch parts pour la table, y compris pour les parties de données auxquelles aucun patch ne doit être appliqué.
  • De petites mises à jour, si elles sont trop fréquentes, peuvent entraîner une erreur « too many parts ». Il est recommandé de regrouper plusieurs mises à jour dans une seule requête, par exemple en plaçant les identifiants à mettre à jour dans une seule clause IN de la clause WHERE
  • Les mises à jour légères sont conçues pour mettre à jour de petits volumes de lignes (jusqu’à environ 10 % de la table). Si vous devez en mettre à jour davantage, il est recommandé d’utiliser la mutation ALTER TABLE ... UPDATE

Opérations concurrentes

Contrairement aux mutations lourdes, les mises à jour légères n’attendent pas la fin des fusions/mutations en cours. La cohérence des mises à jour légères concurrentes est régie par les paramètres update_sequential_consistency et update_parallel_mode.

Autorisations pour UPDATE

UPDATE nécessite le privilège ALTER UPDATE. Pour autoriser les instructions UPDATE sur une table donnée pour un utilisateur donné, exécutez :

Détails de l’implémentation

Les patch parts sont identiques aux parts ordinaires, mais ne contiennent que les colonnes mises à jour et plusieurs colonnes système :
  • _part - le nom de la part d’origine
  • _part_offset - le numéro de ligne dans la part d’origine
  • _block_number - le numéro de bloc de la ligne dans la part d’origine
  • _block_offset - le décalage du bloc de la ligne dans la part d’origine
  • _data_version - la version des données mises à jour (numéro de bloc alloué à la requête UPDATE)
En moyenne, cela représente environ 40 octets de surcoût par ligne mise à jour dans les patch parts (données non compressées). Les colonnes système aident à trouver les lignes de la part d’origine qui doivent être mises à jour. Les colonnes système sont liées aux colonnes virtuelles de la part d’origine, qui sont ajoutées lors de la lecture si des patch parts doivent être appliquées. Les patch parts sont triées par _part et _part_offset. Les patch parts appartiennent à des partitions différentes de la part d’origine. L’identifiant de partition de la patch part est patch-<hash of column names in patch part>-<original_partition_id>. Par conséquent, les patch parts contenant des colonnes différentes sont stockées dans des partitions différentes. Par exemple, trois mises à jour SET x = 1 WHERE <cond>, SET y = 1 WHERE <cond> et SET x = 1, y = 1 WHERE <cond> créeront trois patch parts dans trois partitions différentes. Les patch parts peuvent être fusionnées entre elles afin de réduire le nombre de patchs appliqués aux requêtes SELECT et de diminuer le surcoût. La fusion des patch parts utilise l’algorithme de fusion de type ReplacingMergeTree, avec _data_version comme colonne de version. Par conséquent, les patch parts stockent toujours la version la plus récente de chaque ligne mise à jour dans la part. Les mises à jour légères n’attendent pas la fin des fusions et mutations en cours et utilisent toujours un instantané actuel des parties de données pour exécuter une mise à jour et produire une patch part. De ce fait, il peut y avoir deux cas d’application des patch parts. Par exemple, si nous lisons la part A, nous devons appliquer la patch part X :
  • si X contient la part A elle-même. Cela se produit si A ne participait pas à une fusion lorsque UPDATE a été exécuté.
  • si X contient les parts B et C, qui sont couvertes par la part A. Cela se produit si une fusion (B, C) -> A était en cours lorsque UPDATE a été exécuté.
Pour ces deux cas, il existe respectivement deux façons d’appliquer les patch parts :
  • Utiliser une fusion sur les colonnes triées _part, _part_offset.
  • Utiliser une jointure sur les colonnes _block_number, _block_offset.
Le mode jointure est plus lent et consomme plus de mémoire que le mode fusion, mais il est utilisé moins souvent.
Dernière modification le 24 juillet 2026