使用 SQL 快速删除数百万行数据的实践记录
作者:ZWZhangYu
描述
删除表大批量数据,这是一个比较少的事件。 但在实际的业务开发中或者数据测试也会遇到这种情况。比如定期从日志大表中删除几百万的数据记录;删除表数据的方式有多种,操作起来也很简单。但是这里存在一个问题, 删除大量行可能会很慢。 并且有可能需要更长的时间,因为另一个会话已锁定您要删除的数据。
根据我们所熟知的使用SQL删除数据有三个方式:
1:DELETE,可以添加where条件,速度较慢,锁表
2:truncate ,会删除表所有数据,速度快
3:drop,删除数据以及表结构,慎用
实践
【1】对于truncate 和drop不在本次的讨论范围,虽然这俩种方式很快,但是破坏性太大。注意日常开发中所有删除操作必须添加条件。
【2】对于几十万以上数据的删除不建议使用DELETE FROM TABLE WHERE的方式,该操作非常耗时,效率很差。
【3】对于大批量数据的删除需求实现可以通过Create-Table-as-Select方式处理,在表中插入行比删除它们更快。 使用 create-table-as-select (CTAS) 将数据加载到新表中的速度更快。
create table table_name_temp select * from source_table where XX=?
通过CTAS将不予删除的数据保留到一个临时表中,然后再通过SWAP的方式将临时表作为原表,通过这种方式完成大批量数据删除
【4】个人不建议上述的方式建表,上面的建表方式新表是不会复制原表的索引结构的,如果这个是一个大表那么后面单独加索引也是一个问题。建议使用 CREATE TABLE XXX (LIKE XXX);方式建表,这个会复制相关的索引结构数据
【5】具体操作步骤
-- 复制表结构 CREATE TABLE tableB (LIKE tableA); -- 插入筛选数据 INSERT into tableB SELECT * from tableA where XXX = ?; -- 重命名,替换 rename table tableA to tableC; rename table tableB to tableA; -- 删除旧表 DROP TABLE tableC;
注意:其中俩次rename可以先drop然后一次的rename,但是考虑到数据安全,毕竟是大数量数据删除,还是多操作一步,替换后自己检查下,然后再删除旧表,稳妥些
【6】通过delete删除上百万的数据耗时不清楚具体耗时,反正自己等待了十多钟都没有结果,通过select * from sys.session WHERE conn_id!=connection_id();
查询看一直在执行。通过上面的方式500万的数据不到1分钟,还是比较快的。
【7】小技巧,如果你的大表有递增的ID,删除的或者保留数据的能够以ID作为划分的那么select的条件可以通过这里进行优化,那么操作效率会更快。
【8】如果是oracle,那么还可以使用 alter table … move 来更改存储行的表空间
alter table tableName move including rows where XXX=?
到此这篇关于如何使用 SQL 快速删除数百万行数据的文章就介绍到这了,更多相关SQL 删除数百万行数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!