将MySQL去重操作优化到极致之三弹连发:巧用索引与变量
Posted wzy0623
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将MySQL去重操作优化到极致之三弹连发:巧用索引与变量相关的知识,希望对你有一定的参考价值。
元旦假期收到阿里吴老师来电,被告知已将mysql查重SQL优化到极致:100万原始数据,其中50万重复,把去重后的50万数据写入目标表只需要9秒钟。这是一个惊人的数字,要知道仅是insert 50万条记录也需要些时间的。于是来了兴趣,自己实验、思考、总结做了一遍。一、问题提出
源表t_source结构如下:
item_id int,
created_time datetime,
modified_time datetime,
item_name varchar(20),
other varchar(20)
1. 源表中有100万条数据,其中有50万created_time和item_name重复。
2. 要把去重后的50万数据写入到目标表。
3. 重复created_time和item_name的多条数据,可以保留任意一条,不做规则限制。
二、实验环境
Linux虚机:CentOS release 6.4;8G内存;100G机械硬盘;双物理CPU双核,共四个处理器;MySQL 5.6.14。
三、建立测试表和数据
1. 建立源表
create table t_source
(
item_id int,
created_time datetime,
modified_time datetime,
item_name varchar(20),
other varchar(20)
);
2. 建立目标表
create table t_target like t_source;
3. 生成100万测试数据,其中有50万created_time和item_name重复
delimiter //
create procedure sp_generate_data()
begin
set @i := 1;
while @i<=500000 do
set @created_time := date_add('2017-01-01',interval @i second);
set @modified_time := @created_time;
set @item_name := concat('a',@i);
insert into t_source
values (@i,@created_time,@modified_time,@item_name,'other');
set @i:=@i+1;
end while;
commit;
set @last_insert_id := 500000;
insert into t_source
select item_id + @last_insert_id,
created_time,
date_add(modified_time,interval @last_insert_id second),
item_name,
'other'
from t_source;
commit;
end
//
delimiter ;
call sp_generate_data();
源表没有主键或唯一性约束,有可能存在两条完全一样的数据,所以再插入一条记录模拟这种情况。
insert into t_source
select * from t_source where item_id=1;
commit;
查询总记录数和去重后的记录数图一所示。
select count(*),count(distinct created_time,item_name) from t_source;
以上是关于将MySQL去重操作优化到极致之三弹连发:巧用索引与变量的主要内容,如果未能解决你的问题,请参考以下文章
JAVA面试题之三—Mysql索引了解嘛?怎么优化查询效率?
MySQL: 17 MySQL是如何将LRU链表的使用性能优化到极致的?