在生产环境使用doris的时候,我们经常会涉及到删除数据的需求。大家是不是还在习惯使用delete from table where xxx=xxxx的形式?
其实在doris中,一般不提倡使用delete来删除数据,这是因为每次执行delete的时候回生成一个空的rowset来记录删除条件,并产生一个新的数据版本,每次读取都要对删除条件进行过滤。如果频繁删除或者删除条件过多,都会严重影响查询性能。所以这就是doris官方也不推荐频繁的使用delete来删除数据的原因。
在doris中其实提供了快速批量删除的功能,此快速批量删除仅限unique模型,他的原理是:
1、在创建表的时候自动创建隐藏字段:__DORIS_DELETE_SIGN__,0:代表存在,1:代表已删除 __DORIS_VERSION_COL__:代表版本信息 2、删除数据是把__DORIS_DELETE_SIGN__的值从0修改为1。 3、等待后台自动compaction的时候,会把__DORIS_DELETE_SIGN__=1的文件进行过滤合并掉。 4、查询的时候默认添加上__DORIS_DELETE_SIGN__=0的条件,相当于select * from table where __DORIS_DELETE_SIGN__=0
基于上诉的原理,我们在进行批量删除的时候就非常方便,直接使用insert语句就可以进行操作,下面我们来演示一下:
一、在fe.conf中配置支持批量删除
这里一般我们在生产环境中都是做的必备配置,具体的配置属性是:
enable_batch_delete_by_default=true
配置之后,记得重启fe节点,如果是集群的话,则都要挨个修改下。
开启此项配置之后,在doris上创建的表都会自动被添加上两个隐藏列:
__DORIS_DELETE_SIGN__ __DORIS_VERSION_COL__
二、创建表
这里创建一张orders的表来进行演示,建表语句是:
CREATE TABLE `orders` ( `order_id` int NULL, `user_id` int NULL, `order_status` int NULL, `payment_method` int NULL, `payable_amount` decimal(38,9) NULL, `cts` date NULL ) ENGINE=OLAP UNIQUE KEY(`order_id`) DISTRIBUTED BY HASH(`order_id`) BUCKETS 2 PROPERTIES ( "replication_allocation" = "tag.location.default: 1" );
创建完成之后,我们设置下环境:
#设置环境显示出隐藏列 SET show_hidden_columns=true #查看表信息 desc orders;
可以看到当前表有两个多余的字段,分别是:
__DORIS_DELETE_SIGN__ __DORIS_VERSION_COL__
三、准备数据
这里使用stream load的方式来导入数据,因为日常我们导入大批量数据的话,一般都使用stream load 或者flink cdc等形式导入数据,效率非常快。所以这里我们准备两个数据,分别是:
insert.data
1,1,1,1,20.50,'2024-12-17' 2,2,2,2,18.95,'2024-12-17'
delete.data
2
这里我们的意图是:
1、插入数据进行完整。 2、删除的数据根据id删除即可。
四、插入数据
接下来演示插入数据,使用stream load的形式执行insert.data
curl --location-trusted -u root: -H "column_separator:," -H "columns: order_id, user_id, order_status, payment_method, payable_amount, cts" -T insert.data http://127.0.0.1:38030/api/test/orders/_stream_load
执行完毕之后,会显示Success的状态
此时我们查询下orders表的数据:
可以看到这里把两条数据给插入进去了,同时__DORIS_DELETE_SIGN__的值是0,代表数据真实存在的,不是删除状态的。
备注:
1、上面能查看到__DORIS_DELETE_SIGN__值得是因为我们在当前的查询session中设置了SET show_hidden_columns=true;真实查询的session这个值是false,即查询效果如下:
2、一般实际使用的时候我们也不会涉及到查询__DORIS_DELETE_SIGN__值。
五、插入删除数据
接下来我们再执行刚才的delete.data数据,把它插入进去
curl --location-trusted -u root: -H "column_separator:," -H "columns: order_id" -H "merge_type: DELETE" -T delete.data http://127.0.0.1:38030/api/test/orders/_stream_load
在删除数据的时候,我们设置了http的头信息:
merge_type: DELETE
这里就是告诉daoris,当前插入的数据需要让doris自动去变更__DORIS_DELETE_SIGN__的值,也就是让doris把__DORIS_DELETE_SIGN__字段的值从0修改为1。上面执行完毕之后,我们查询下结果:
可以看到结果中少了一条数据,成功的实现了删除数据。然后我们把session的隐藏字段打开:
可以看到doris自动把id为2的数据的__DORIS_DELETE_SIGN__值修改成了1。待后续doris触发compation的时候,他就会自动把__DORIS_DELETE_SIGN__=1的数据给删除掉。
以上就是doris中提供批量删除的案例。
备注:
1、doris必须配置enable_batch_delete_by_default=true之后才能支持批量删除,默认是不支持的,在fe.conf中配置此项配置之后,必须重启fe,然后新创建的表才能支持批量删除。 2、如果想要在配置enable_batch_delete_by_default=true之前创建的表支持批量删除,那么需要在session中设置:ALTER TABLE tablename ENABLE FEATURE "BATCH_DELETE" 3、doris的批量删除核心就是把__DORIS_DELETE_SIGN__这个隐藏值从0修改为1 4、在调试查看阶段的时候,我们在session中开启SET show_hidden_columns=true;这里仅是为了调试,生产环节切勿在业务查询session中设置此项,不然会把删除的数据给查询出来,导致数据错误。 5、正常情况下,所有的session中show_hidden_columns属性值为false;生产环境切勿修改此值。doris在查询的时候会默认添加上 where __DORIS_DELETE_SIGN__=0,保证查询的数据是准确的。
发表评论