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.
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ètrelightweight_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 commandeTRUNCATE 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
WHEREcomplexe dans une requêteDELETE. - 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
-
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êteALTER TABLE ... DELETE. Le masque est implémenté sous la forme d’une colonne système cachée_row_existsqui stockeTruepour toutes les lignes visibles etFalsepour 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. -
Les requêtes
SELECTsont transformées pour inclure le masque Lorsqu’une colonne masquée est utilisée dans une requête, la requêteSELECT ... FROM table WHERE conditionest étendue en interne avec le prédicat sur_row_existset devient :Lors de l’exécution, la colonne_row_existsest 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. -
Les requêtes
DELETEmettent à jour le masque selon le mode sélectionné Avec les patch parts,DELETE FROM table WHERE conditionest traduit enUPDATE 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éfautalter_update,DELETE FROM table WHERE conditionest traduit en mutationALTER TABLE table UPDATE _row_exists = 0 WHERE condition. En interne, cette mutation est exécutée en deux étapes :-
Une commande
SELECT count() FROM table WHERE conditionest exécutée pour chaque part afin de déterminer si elle est concernée. -
À 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_existsde 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.
DELETEléger utilisant la technique du masquage offre de meilleures performances que leALTER TABLE ... DELETEtraditionnel, car il ne réécrit pas les fichiers de toutes les colonnes pour les parts concernées. -
Une commande