项目中,我们常常会发现有些表的数据量增长过快,SQL 扫描的时候,需扫很多无效的数据,导致SQL 慢了下来。有些数据业务上
并不是非常的重要,或者具有时效性,如果使用DELETE 将其删除,那么是否能优化性能呢?
创建测试表
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL DEFAULT '' COMMENT '姓名',
`age` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'age',
`gender` char(1) NOT NULL DEFAULT 'M' COMMENT '性别',
`phone` varchar(16) NOT NULL DEFAULT '' COMMENT '手机号',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
KEY `idx_name` (`name`),
KEY `idx_phone` (`phone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';
插入 100w 的数据
DELIMITER $$
DROP PROCEDURE IF EXISTS insert_user_data$$
CREATE PROCEDURE insert_user_data(num INTEGER)
BEGIN
DECLARE v_i int unsigned DEFAULT 0;
SET autocommit= 0;
WHILE v_i < num DO
insert into user(`name`, age, gender, phone) values (CONCAT('lyn',v_i), mod(v_i,120), 'M', CONCAT('152',ROUND(RAND(1)*100000000)));
SET v_i = v_i+1;
END WHILE;
COMMIT;
END $$
DELIMITER ;
call insert_user_data(1000000);
查询性能
select id, age ,phone from user where name like 'lyn12%';
-- 取10次查询样本响应时间平均值
-- 20.1ms
-- 18.5ms
-- 16.6ms
-- 16.7ms
-- 20.8ms
-- 14.9ms
-- 14.4ms
-- 13.8ms
-- 17.5ms
-- 15.3ms
-- 均值:15.19 ms
删除 50w数据,再进行查询
delete from user limit 500000;
select id, age ,phone from user where name like 'lyn12%';
-- 取10次查询样本响应时间平均值
-- 44.3ms
-- 30.0ms
-- 27.9ms
-- 27.2ms
-- 32.9ms
-- 39.7ms
-- 31.2ms
-- 28.7ms
-- 38.2ms
-- 38.8ms
-- 均值:30.07ms
mysql delete 操作并不会直接把数据删除,而且会增加碎片率。