跳到主要内容
跳到主要内容

删除概述

在 ClickHouse 中,有几种方法可以删除数据,每种方法都有其自身的优点和性能特征。您应根据数据模型和您打算删除的数据量选择适当的方法。

方法语法何时使用
轻量级删除DELETE FROM [table]用于删除少量数据时。行会立即在后续的所有 SELECT 查询中被过滤掉,但最初仅内部标记为删除,并未从磁盘中移除。
删除突变ALTER TABLE [table] DELETE当数据必须立即从磁盘中删除时使用(例如,为了合规)。对 SELECT 性能有负面影响。
截断表TRUNCATE TABLE [db.table]高效地从表中移除所有数据。
删除分区DROP PARTITION高效地从一个分区中移除所有数据。

下面是 ClickHouse 中删除数据的不同方法的总结:

轻量级删除

轻量级删除使行被立即标记为已删除,从而在后续的所有 SELECT 查询中可以自动滤除这些行。这些被删除行的后续移除发生在自然合并周期内,因此减少了 I/O。因此,可能会在不确定的时间段内,数据实际上并未从存储中删除,仅被标记为已删除。如果您需要保证数据被删除,请考虑上述的突变命令。

-- delete all data from 2018 with a lightweight delete. Not recommended.
DELETE FROM posts WHERE toYear(CreationDate) = 2018

使用轻量级 DELETE 语句删除大量数据也可能会对 SELECT 查询性能产生负面影响。该命令也不与具有投影的表兼容。

请注意,在操作中使用了突变来标记已删除的行(添加一个 _row_exists 列),因此会产生一些 I/O。

一般来说,如果可以容忍被删除数据在磁盘上的存在(例如在非合规情况下),则应优先选择轻量级删除而不是突变。如果需要删除所有数据,则仍应避免此方法。

阅读更多关于 轻量级删除

删除突变

可以通过 ALTER TABLE ... DELETE 命令发出删除突变,例如:

-- delete all data from 2018 with a mutation. Not recommended.
ALTER TABLE posts DELETE WHERE toYear(CreationDate) = 2018

这些可以同步执行(如果没有副本则默认如此)或异步执行(由 mutations_sync 设置决定)。这些操作非常耗费 I/O,会重写与 WHERE 表达式匹配的所有分区片段。此过程没有原子性 - 部分在准备好时会被替换为突变部分,而在突变过程中开始执行的 SELECT 查询将看到已突变的部分数据以及尚未突变的部分数据。用户可以通过 systems.mutations 表跟踪进度状态。这些是 I/O 密集型操作,应谨慎使用,因为它们会影响集群的 SELECT 性能。

阅读更多关于 删除突变

截断表

如果需要删除表中的所有数据,请使用下面的 TRUNCATE TABLE 命令。这是一个轻量级操作。

TRUNCATE TABLE posts

阅读更多关于 TRUNCATE TABLE

删除分区

如果您为数据指定了自定义分区键,可以高效地删除分区。避免高基数分区。

ALTER TABLE posts (DROP PARTITION '2008')

阅读更多关于 DROP PARTITION

更多资源