Skip to main content
L’instruction DELETE légère supprime les lignes de la table [db.]table qui correspondent à l’expression expr. Elle est disponible uniquement pour la famille de moteurs de table *MergeTree.
On l’appelle “lightweight DELETE” pour le distinguer de la commande ALTER TABLE … DELETE, qui est une opération lourde.

Exemples

DELETE léger ne supprime pas les données immédiatement

DELETE léger marque les lignes comme supprimées sans les retirer immédiatement du stockage. Par défaut, il utilise une mutation. Selon le paramètre lightweight_delete_mode, il peut aussi utiliser des patch parts. Dans le mode par défaut fondé sur les mutations, les instructions DELETE attendent que le marquage des lignes comme supprimées soit terminé avant de renvoyer la réponse. Cela peut prendre beaucoup de temps si le volume de données est important. Vous pouvez aussi l’exécuter de manière asynchrone en arrière-plan à l’aide du paramètre lightweight_deletes_sync. S’il est désactivé, l’instruction DELETE renverra immédiatement, mais les données pourront encore rester visibles dans les requêtes jusqu’à la fin de la mutation en arrière-plan. Dans les deux modes, les lignes supprimées restent dans le stockage jusqu’à leur suppression effective. Les fusions en arrière-plan les retirent normalement des parts concernées. Pour appliquer explicitement le masque de suppression, utilisez ALTER TABLE ... APPLY DELETED MASK, qui effectue une mutation coûteuse. Si vous devez garantir que vos données sont supprimées du stockage dans un délai prévisible, envisagez d’utiliser le paramètre de table min_age_to_force_merge_seconds. Vous pouvez aussi utiliser la commande ALTER TABLE … DELETE. Notez que la suppression de données à l’aide de ALTER TABLE ... DELETE peut consommer des ressources importantes, car elle recrée toutes les parts affectées.

Choisir le mode de suppression

Le paramètre lightweight_delete_mode permet de choisir entre les suppressions par mutation (mode par défaut) et les mises à jour légères qui créent des patch parts contenant _row_exists = 0 pour les lignes supprimées. Les requêtes appliquent ces correctifs avant la suppression physique des données. Consultez la référence du paramètre pour connaître les modes disponibles et les conditions requises pour les mises à jour légères pour vérifier les prérequis. Lorsque des patch parts sont utilisées, lightweight_deletes_sync n’attend pas les autres répliques : avec ReplicatedMergeTree, celles-ci peuvent encore renvoyer des lignes supprimées tant qu’elles n’ont pas reçu le correctif.

Suppression de grandes quantités de données

Les suppressions massives peuvent dégrader les performances de ClickHouse. Si vous cherchez à supprimer toutes les lignes d’une table, envisagez d’utiliser la commande TRUNCATE TABLE. Si vous prévoyez des suppressions fréquentes, envisagez d’utiliser une clé de partitionnement personnalisée. Vous pourrez ensuite utiliser la commande ALTER TABLE ... DROP PARTITION pour supprimer rapidement toutes les lignes associées à cette partition.

Limites du DELETE léger

DELETE légers avec des projections

Par défaut, DELETE ne fonctionne pas sur les tables comportant des projections. En effet, des lignes d’une projection peuvent être affectées par une opération DELETE. Il existe toutefois un paramètre MergeTree, lightweight_mutation_projection_mode, pour modifier ce comportement.

Considérations relatives aux performances lors de l’utilisation de DELETE léger

La suppression de grands volumes de données avec l’instruction DELETE légère peut dégrader les performances des requêtes SELECT. Les éléments suivants peuvent également dégrader les performances de DELETE léger :
  • Une condition WHERE complexe dans une requête DELETE.
  • Pour les suppressions basées sur des mutations, une longue file d’attente de mutations : les mutations d’une table sont exécutées séquentiellement.
  • La table concernée contient un très grand nombre de parts.
  • Lors de l’utilisation de suppressions basées sur des mutations, une grande quantité de données stockées dans des parts compacts. Dans un part compact, toutes les colonnes sont stockées dans un seul fichier et doivent être réécrites ensemble.

Autorizations de suppression

DELETE requiert le privilège ALTER DELETE. Pour autoriser les instructions DELETE sur une table spécifique pour un utilisateur donné, exécutez la commande suivante :

Fonctionnement interne des DELETE légers dans ClickHouse

  1. Un « masque » est appliqué aux lignes concernées Lorsqu’une requête DELETE FROM table ... est exécutée, ClickHouse enregistre un masque dans lequel chaque ligne est marquée soit comme « existante », soit comme « supprimée ». Ces lignes « supprimées » sont alors exclues des requêtes suivantes. Toutefois, les lignes ne sont physiquement supprimées que plus tard, généralement lors des fusions en arrière-plan. L’écriture de ce masque est bien plus légère que ce qu’implique une requête ALTER TABLE ... DELETE. Le masque est implémenté sous la forme d’une colonne système cachée _row_exists qui stocke True pour toutes les lignes visibles et False pour celles qui sont supprimées. Cette colonne n’est présente dans une part que si certaines de ses lignes ont été supprimées. Elle n’existe pas lorsqu’une part a toutes ses valeurs égales à True.
  2. Les requêtes SELECT sont transformées pour inclure le masque Lorsqu’une colonne masquée est utilisée dans une requête, la requête SELECT ... FROM table WHERE condition est étendue en interne avec le prédicat sur _row_exists et devient :
    Lors de l’exécution, la colonne _row_exists est lue pour déterminer quelles lignes ne doivent pas être renvoyées. S’il y a beaucoup de lignes supprimées, ClickHouse peut déterminer quels granules peuvent être entièrement ignorés lors de la lecture du reste des colonnes.
  3. Les requêtes DELETE mettent à jour le masque selon le mode sélectionné Avec les patch parts, DELETE FROM table WHERE condition est traduit en UPDATE table SET _row_exists = 0 WHERE condition. Les patch parts qui en résultent stockent les modifications du masque pour les lignes supprimées et sont appliquées lors de la lecture et de la fusion des données. Avec le mode par défaut alter_update, DELETE FROM table WHERE condition est traduit en mutation ALTER TABLE table UPDATE _row_exists = 0 WHERE condition. En interne, cette mutation est exécutée en deux étapes :
    1. Une commande SELECT count() FROM table WHERE condition est exécutée pour chaque part afin de déterminer si elle est concernée.
    2. À partir des commandes ci-dessus, les parts concernées sont ensuite mutées, et des liens physiques sont créés pour les parts non concernées. Dans le cas des parts wide, la colonne _row_exists de chaque ligne est mise à jour, et les fichiers de toutes les autres colonnes sont liés physiquement. Pour les parts compact, toutes les colonnes sont réécrites, car elles sont toutes stockées ensemble dans un seul fichier.
    Comme le montrent les étapes ci-dessus, le DELETE léger utilisant la technique du masquage offre de meilleures performances que le ALTER TABLE ... DELETE traditionnel, car il ne réécrit pas les fichiers de toutes les colonnes pour les parts concernées.