背景
研发库,单节点mysql数据库。某日志表数据量过大(千万级别),需要清除部分数据(比如:只保留近一个月的数据)。
措施
使用delete删除符合条件行数据。
问题
执行效率很慢。
原因:”delete语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存 以便进行进行回滚操作。”
文章结尾会给出相关对比
采用创建临时表
- 将要保留的近一个月数据放到临时表中。比如:日志表为t_change_log。
1 | create table t_change_log_tmp as (select * from t_change_log where create_time>'2017-01'); |
注意:此方法创建出的临时表中结构属性会丢失,如表主键等。
调整后1
2
3
4-- 复制表结构
create table t_change_log_tmp like t_change_log;
-- copy数据
insert into t_change_log_tmp (select * from t_change_log where create_time>'2017-01');
引申
- create table like方式会完整地克隆表结构,但不会插入数据,需要单独使用insert into或load data方式加载数据。
- create table as 方式会部分克隆表结构,完整保留数据。
3.create table as select .. where 1=0 会克隆部分表结构,但不克隆数据。- 如果启用了gtid,create table as方式不被支持。收到ERROR 1786 (HY000): CREATE TABLE … SELECT is forbidden when @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1。
使用drop删除老表
1
drop table t_change_log;
重命名临时表为老表
1
alter table t_change_log_tmp rename t_change_log;
其他
drop,truncate,delete对比
1 | 1、drop (删除表):删除内容和定义,释放空间。简单来说就是把整个表去掉.以后要新增数据是不可能的,除非新增一个表。 |