DELETE语句用于删除目标表指定列的行数据。本文为您介绍在Hologres中DELETE语句的用法。

命令介绍

DELETE命令的语法如下所示。

DELETE FROM <table_name> [ * ] [ [ AS ] <alias> ]
    [ WHERE <condition>  ]

参数说明如下表所示。

参数

描述

table_name

目标表的名称。

alias

别名。目标表的替代名称。

condition

删除目标表的条件。

技术原理

DELETE会先写到内存表(Mem Table),然后Flush成文件,如下图所示。在此过程中,如果是行存表,被删除的数据将会被Flush成一个新的小文件,在Compaction的时候做合并成文件块;如果是列存表,系统会在内存中存储一张标记表,然后Flush成标记表文件,标记表文件会记录删除的数据所在的文件号(file id)和行号(row id),然后在Compaction的时候做合并。更多原理请参见Hologres高性能写入技术揭秘DELETE为了提高删除(DELETE)的效率,尽量通过Fixed Plan执行DELETE语句,详情请参见Fixed Plan加速SQL执行,或者建议为表设置合适的主键和索引(Distribution Key,Segment Key,Clustering Key),这样就能快速定位到需要被删除的文件和文件号,否则是全表扫描,对性能有一定的牺牲。对于按照主键点查的SQL(delete from tablename where pk =xxx),行存表的删除效率要高于列存表。

使用限制

  • Hologres暂不支持直接删除分区表父表。您需要删除具体的分区表子表后,才可以删除分区表父表。

  • 如果执行整表数据的清空删除,建议使用TRUNCATE语法,效率远比DELETE更高,参考 TRUNCATE

  • 推荐使用Fixed Plan优化DELETE执行效率,参考 DELETE场景

  • Hologres中的DELETE命令与PostgreSQL的一样,使用标记删除,在下一次Compaction后,存储空间才会被释放。由于采用LSM结构保存内存状态,在DELETE执行之后,有概率存留部分未达到Compaction阈值的临时数据会继续占用存储空间,如需彻底删除,建议使用TRUNCATE。

示例

删除表的示例语句如下。

CREATE TABLE delete_test (
    id INT PRIMARY KEY,
    a INT,
    b text
);

INSERT INTO delete_test VALUES
(1, 10, 'a'),
(2, 30, 'b'),
(3, 50,  ''),
(4, 70, null);



DELETE FROM delete_test AS dt WHERE dt.a = 10;

DELETE FROM delete_test AS dt WHERE dt.b is null;

DELETE FROM delete_test AS dt WHERE dt.b='';
            

更多关于DELETE的详情,请参见PostgreSQL DELETE

常见问题

在执行DELETE命令时,为什么监控指标中存储用量上涨非常多,写入完成后存储用量又下降?delete存储用量

根据DELETE的原理,DELETE时会将老数据做标记,新数据会Flush成新的小文件,后台会将这些小文件做Compaction,在Compaction的过程中就会将老数据给清理掉,并合并新数据。为了删除的速度尽可能的快,后台会先将数据写完,待异步Compaction时再执行压缩和整理,因此会看到在数据删除过程中,数据的存储会一定的膨胀,等Compaction完成后存储会下降,详情请参见技术原理