在 Doris 中如何执行数据删除(Delete)?
在 Apache Doris 中,执行数据删除(Delete)与传统的 OLTP 数据库(如 MySQL)有所不同。因为 Doris 是一个主要用于分析的 OLAP 数据库,底层采用列式存储和类似 LSM-Tree 的架构,因此不推荐像在 MySQL 中那样高频地执行单条数据的 DELETE 操作。
根据不同的业务场景,Doris 提供了 4 种删除数据的方式。以下是详细的指南:
1. 使用 DELETE FROM 语句(条件删除)
这是最符合传统 SQL 习惯的删除方式,适用于低频、少量数据的条件删除。
语法:
DELETE FROM table_name [PARTITION partition_name]
WHERE column_name = 'value';
示例:
-- 删除 user_info 表中 user_id 为 1001 的数据
DELETE FROM user_info WHERE user_id = 1001;
-- 推荐带上分区,删除速度更快,影响范围更小
DELETE FROM sales_record PARTITION (p202310) WHERE store_id = 5;
⚠️ 注意事项:
- 条件限制:
WHERE条件一般只能是基础字段的等值(=)、不等值(>、<)、IN等操作,不支持子查询或JOIN。 - 性能影响:在 Duplicate 或 Aggregate 模型中,
DELETE操作实际上是记录了一个“删除谓词”。查询时会在运行时过滤这些数据,如果积累过多的DELETE操作,会严重拖慢查询性能。真正的数据清理会在系统后台合并(Compaction)时进行。
2. 删除整个分区 DROP PARTITION(最推荐的大批量删除)
如果是按时间过期数据的清理(例如删除上个月的日志),强烈推荐通过删除分区来实现。这是一种元数据操作,速度极快(毫秒级),且不消耗 IO 和 CPU 资源。
语法:
ALTER TABLE table_name DROP PARTITION partition_name;
示例:
-- 删除 2023 年 9 月的分区
ALTER TABLE web_logs DROP PARTITION p202309;
提示:如果是动态分区表(Dynamic Partition),Doris 会根据配置的 TTL 自动删除过期分区,无需手动执行。
3. 通过导入方式进行批量删除(适用于 CDC / 高频更新删除)
如果你是在同步上游数据库(如 MySQL、Oracle)的数据变更,包含了大量的 INSERT、UPDATE 和 DELETE 操作,推荐使用 Unique Key 模型 结合 导入时设置删除标记(Delete Sign) 的方式。
在 Doris 中,内置了一个隐藏列 __DORIS_DELETE_SIGN__。当导入数据时,将该列设为 1,则代表删除对应的主键数据。
Stream Load 示例(通过 cURL):
假设表主键是 user_id,你要删除 user_id=1001 的记录。
curl --location-trusted -u root: \
-H "column_separator:," \
-H "columns: user_id, __DORIS_DELETE_SIGN__" \
-T delete_data.csv \
http://<fe_ip>:8030/api/my_db/user_info/_stream_load
注:delete_data.csv 文件内容为 1001,1
Flink Doris Connector / Routine Load 示例:
如果使用 Flink CDC 接入 MySQL 数据,Connector 默认会自动解析 MySQL binlog 中的 DELETE 事件,并自动映射到 Doris 的 __DORIS_DELETE_SIGN__ 列进行删除,无需手动编写 SQL。
4. 清空全表或分区 TRUNCATE
如果你需要清空整张表或某个分区的所有数据,保留表结构,使用 TRUNCATE。这也是元数据操作,速度极快。
示例:
-- 清空整张表
TRUNCATE TABLE user_info;
-- 清空指定分区
TRUNCATE TABLE sales_record PARTITION (p202310);
💡 Doris 删除操作的最佳实践与总结
- 历史数据清理:绝对优先使用
DROP PARTITION,建表时按时间(天/月)进行RANGE分区。 - 上游 CDC 同步(如 MySQL binlog 同步):使用 Unique Key 模型。在 Doris 2.0 及以上版本中,强烈建议建表时开启
Merge-On-Write(MoW)特性("enable_unique_key_merge_on_write" = "true")。开启后,系统在导入删除/更新数据时会直接处理,查询性能会得到质的飞跃。 - 手动偶尔纠错:使用
DELETE FROM,但尽量指定PARTITION以缩小范围。切忌在程序里写循环单条执行DELETE FROM。 - 全表重刷:使用
TRUNCATE TABLE然后重新导入数据。