删除重复记录,只保留id最大的一条记录的性能测试

环境

测试表的id为是唯一的,或是自增的主键。

mysql不能直接写循环,只能写在存储过程里。

存储过程usp_batch_insert的参数num_count为插入总行数,参数batch_commit为每批提交的行数。

由于是测试,先把bin log关闭。在生产上做删除重复记录操作,不能随意关闭,根据业务而定。

SET session sql_log_bin = 0;

创建测试表t3

CREATE TABLE `t3` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`f1` varchar(32) DEFAULT NULL,
`f2` varchar(32) DEFAULT NULL,
`ctime` datetime(3) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

每批量提交的记录表t3_log

CREATE TABLE `t3_log` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`i` bigint(20) DEFAULT NULL,
`ctime` datetime(3) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

构造数据的存储过程

DELIMITER $$
DROP PROCEDURE IF EXISTS `usp_batch_insert`;
CREATE PROCEDURE `usp_batch_insert`(IN `num_count` int,IN `batch_commit` int)
BEGIN
DECLARE i INT;
SET i = 1;
SET AUTOCOMMIT = 0; WHILE i <= num_count DO
INSERT INTO t3 (f1, f2, ctime)
SELECT REPLACE(UUID(), '-', '') AS a, REPLACE(UUID(), '-', '') AS b, NOW(3) AS c;
SET i = i + 1;
IF MOD(i, batch_commit) <= 0 THEN
INSERT INTO t3_log (i, ctime) VALUES (i, NOW(3));
COMMIT;
END IF;
END WHILE; SET AUTOCOMMIT = 1;
END; $$
DELIMITER ;

生成200万的测试数据

CALL usp_batch_insert(2000000, 5000);

把一部分数据重复

INSERT INTO t3 (f1,f2,ctime)
SELECT f1, f2, NOW(3) FROM t3 LIMIT 123456,10000; INSERT INTO t3 (f1,f2,ctime)
SELECT f1, f2, NOW(3) FROM t3 LIMIT 15234567,254321; INSERT INTO t3 (f1,f2,ctime)
SELECT f1, f2, NOW(3) FROM t3 LIMIT 345678,654321; INSERT INTO t3 (f1,f2,ctime)
SELECT f1, f2, NOW(3) FROM t3 LIMIT 654321,45678; INSERT INTO t3 (f1,f2,ctime)
SELECT f1, f2, NOW(3) FROM t3 LIMIT 886,123456; INSERT INTO t3 (f1,f2,ctime)
SELECT f1, f2, NOW(3) FROM t3 LIMIT 15,2000;

数据已经构造完,全表280多万行记录,需要删除的数据有80多万。

下面就来测试下全过程的时间,总耗时是216秒,其中删除部分约29秒。

如果要保留最小id的那行记录,则把max()函数修改为min()函数。

CREATE OR REPLACE TABLE _tmp_t3 (id INT NOT NULL PRIMARY KEY);

INSERT INTO _tmp_t3 (id)
SELECT id
FROM t3
WHERE id NOT IN (
SELECT maxid FROM
(SELECT max(id) AS maxid FROM t3
GROUP BY f1, f2
) b
); DELETE a FROM t3 as a INNER JOIN _tmp_t3 as b on b.id = a.id;

如果29秒可能会影响业务,可以做成存储过程,分批删除。

DELIMITER $$
DROP PROCEDURE IF EXISTS `usp_batch_delete`; CREATE PROCEDURE `usp_batch_delete`(IN `batch_commit` int)
BEGIN
DECLARE i INT;
DECLARE num_count INT;
SET i = 1;
SELECT MAX(id) INTO num_count FROM _tmp_t3;
SET AUTOCOMMIT = 0; WHILE i <= num_count DO DELETE a FROM t3 as a INNER JOIN _tmp_t3 as b on b.id = a.id AND b.id = i;
SET i = i + 1; IF MOD(1, batch_commit) >= 0 THEN
COMMIT;
END IF; END WHILE; SET AUTOCOMMIT = 1;
END; $$
DELIMITER ;

MariaDB删除重复记录性能测试的更多相关文章

  1. MariaDB删除重复记录

    不管是程序BUG,还是业务变更,重复数据这个老生常谈的问题,总是会出现.以下是我在MariaDB或是MySQL下处理的一些经验.在SQL Server中,使用窗口函数是很容易实现的.不过听说MySQL ...

  2. mysql删除重复记录语句的方法

    例如: id name value 1 a pp 2 a pp 3 b iii 4 b pp 5 b pp 6 c pp 7 c pp 8 c iii id是主键 要求得到这样的结果 id name ...

  3. mysql 删除重复记录语句

    mysql 根据条件删除重复记录 只保留最小id的重复数据 DELETEFROM newsWHERE news_id IN ( SELECT a.news_id FROM ( SELECT news_ ...

  4. sql查询重复记录、删除重复记录方法大全

    查找所有重复标题的记录:SELECT *FROM t_info aWHERE ((SELECT COUNT(*)FROM t_infoWHERE Title = a.Title) > 1)ORD ...

  5. mysql 数据表中查找、删除重复记录

    为了性能考虑,在阅读之前提醒大家,如果有子查询,子查询查询到的数据最好不要超过总数据量的30%. 查询有重复数据的记录 select * from F group by a,b,c,d having ...

  6. [SQL]查询及删除重复记录的SQL语句

    一:查询及删除重复记录的SQL语句1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断select * from peoplewhere peopleId in (select ...

  7. MySQL查询及删除重复记录的方法

    查询及删除重复记录的方法(一)1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断select * from peoplewhere peopleId in (select p ...

  8. Oracle 查询并删除重复记录的SQL语句

    查询及删除重复记录的SQL语句 1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断select * from peoplewhere peopleId in (select  ...

  9. mysql插入数据与删除重复记录的几个例子(收藏)

    mysql插入数据与删除重复记录的几个例子 12-26shell脚本实现mysql数据的批量插入 12-26mysql循环语句插入数据的例子 12-26mysql批量插入数据(insert into ...

随机推荐

  1. Windows+VS2012环境下编译调试MySQL源码 转

    http://m.blog.csdn.net/blog/SnowyWolf/18952643

  2. [Asp.Net web api]基于自定义Filter的安全认证

    摘要 对第三方开放的接口,处于安全的考虑需要对其进行安全认证,是否是合法的请求.目前在项目中也遇到这种情况,提供的接口因为涉及到客户铭感数据,所以在调用的时候,不能直接暴露,需要有一个认证的机制.所以 ...

  3. Access-Control-Allow-Origin,跨域

    1.浏览器的同源安全策略 浏览器只允许请求当前域的资源,而对其他域的资源表示不信任.那怎么才算跨域呢? 请求协议http,https的不同 域domain的不同 端口port的不同 好好好,大概就是这 ...

  4. Spring初始化完成后直接执行一个方法,初始化数据(解决方法被重复执行两次的情况)

    在做WEB项目时,经常在项目第一次启动时利用WEB容器的监听.Servlet加载初始化等切入点为数据库准备数据,这些初始化数据 是系统开始运行前必须的数据,例如权限组.系统选项.默认管理员等等.但是项 ...

  5. 【spring cloud】【IDEA】【Maven】spring cloud多模块打包,打包的jar包只有几k,jar包无法运行,运行报错:no main manifest attribute, in /ms-eureka.jar

    ======================================================================================== 引申:maven打包多 ...

  6. JAVA nio 2 和 Path 类简介

    想要初步了解 NIO.2 API,也就是通常所说的“JSR203: More New I/O APIs for the Java Platform”,最好的切入点就是新的抽象类 java.nio.fi ...

  7. [翻译] Working with NSURLSession: AFNetworking 2.0

    Working with NSURLSession: AFNetworking 2.0   简单翻译,有很多错误,看官无法理解处请英文原文对照. http://code.tutsplus.com/tu ...

  8. 基于libhid/libusb进行开发

    操作环境:ubuntu,基于libhid/libusb进行开发   libusb介绍: libusb 设计了一系列的外部API 为应用程序所调用,通过这些API应用程序可以操作硬件,从libusb的源 ...

  9. Objective-C:OC内部可变对象和不可变对象的深(复制)拷贝问题思考:

    OC内部:可变对象和不可变对象的深(复制)拷贝问题思考:   不可变对象:  例如NSString对象,因为NSString对象是常量字符串,所以,不可以更改其内容,但是可以修改指向该字符串的指针指向 ...

  10. 我所遭遇过的游戏中间件--FlashOcx

    使用Flash做游戏界面的另一种方式是通过Abode提供flash.ocx处理Flash界面.将Flash图像通过GDI绘制出来后,再将图像数据拷贝到一个D3D的纹理结构中,最后由引擎的D3D接口进行 ...