将MySQL去重操作优化到极致之三弹连发
发表于:2025-02-12 作者:千家信息网编辑
千家信息网最后更新 2025年02月12日,将MySQL去重操作优化到极致之三弹连发(一):巧用索引与变量http://blog.csdn.net/wzy0623/article/details/54377986实验准备:MySQL 5.6.1
千家信息网最后更新 2025年02月12日将MySQL去重操作优化到极致之三弹连发
http://blog.csdn.net/wzy0623/article/details/54377986
实验准备:
MySQL 5.6.14
执行计划如下:
![](https://www.aqdb.cn/uploadfile/d3/98a8cc10.jpg)
可以看到MySQL 给 t1表的item_id自动创建了一个索引.
2.使用MySQL特性
效率尚可,省时省力.
3.使用自定义变量
执行计划如下:
![](https://www.aqdb.cn/uploadfile/0d/6468e5d8.jpg)
以上都是没有添加任何索引的情况.
添加索引如下:
create index idx_sort on t_source(created_time,item_name,item_id);
analyze table t_source;
创建索引之后,
使用表连接查询方式耗时11s,小幅提升.
使用MySQL特性的方式,耗时11-12s,反而更慢.
使用MySQL自定义变量的方式,耗时还是18s.
很显然,MySQL自定义变量的方式,其实没有利用索引.
最终改进SQL
耗时11s.
该语句具有以下特点。
(1)消除了嵌套子查询,只需要对t_source表进行一次全索引扫描,查询计划已达最优。
(2)无需distinct二次查重。
(3)变量判断与赋值只出现在where子句中。
(4)利用索引消除了filesort。
强制通过索引idx_sort查找数据行 -> 应用where筛选器 -> 处理select列表 -> 应用order by子句。
为了使变量能够按照created_time和item_name的排序顺序进行赋值和比较,必须按照索引顺序查找数据行。这里的force index (idx_sort)提示就起到了这个作用,必须这样写才能使整条查重语句成立。否则,因为先扫描表才处理排序,因此不能保证变量赋值的顺序,也就不能确保查询结果的正确性。order by子句同样不可忽略,否则即使有force index提示,MySQL也会使用全表扫描而不是全索引扫描,从而使结果错误。
索引同时保证了created_time,item_name的顺序,避免了文件排序。force index (idx_sort)提示和order by子句缺一不可,索引idx_sort在这里可谓恰到好处、一举两得。
查询语句开始前,先给变量初始化为数据中不可能出现的值,然后进入where子句从左向右判断。先比较变量和字段的值,再将本行created_time和item_name的值赋给变量,按created_time,item_name的顺序逐行处理。item_name是字符串类型,(@b:=item_name)不是有效的布尔表达式,因此要写成(@b:=item_name) is not null。
"insert into t_target select * from t_source group by created_time,item_name;"的写法,它受"sql_mode='ONLY_FULL_GROUP_BY'"的限制。
运行耗时和原文有出入,可能是因为我的环境是SSD的缘故.
另外,避免回表的开销,可以增加索引的字段
drop index idx_sort on t_source;
create index idx_sort on t_source(created_time,item_name,item_id,modified_time,other);
analyze table t_source;
使用上述索引,终极改进的SQL 耗时可以降到 9.5s
参考:
http://blog.csdn.net/wzy0623/article/details/54378367
http://blog.csdn.net/wzy0623/article/details/54378575
将MySQL去重操作优化到极致之三弹连发(一):巧用索引与变量
http://blog.csdn.net/wzy0623/article/details/54377986
实验准备:
MySQL 5.6.14
- create table t_source
- (
- item_id int,
- created_time datetime,
- modified_time datetime,
- item_name varchar(20),
- other varchar(20)
- );
- create table t_target like t_source;
- 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;
- truncate t_target;
- insert into t_target
- select distinct t1.* from t_source t1,
- (select min(item_id) item_id,created_time,item_name from t_source t3 group by created_time,item_name) t2
- where t1.item_id = t2.item_id;
- commit;
执行计划如下:
![](https://www.aqdb.cn/uploadfile/d3/98a8cc10.jpg)
可以看到MySQL 给 t1表的item_id自动创建了一个索引.
2.使用MySQL特性
- truncate t_target;
- insert into t_target
- select min(item_id),created_time,modified_time,item_name,other
- from t_source
- group by created_time,item_name;
- commit;
效率尚可,省时省力.
3.使用自定义变量
- set @a:='0000-00-00 00:00:00';
- set @b:=' ';
- set @f:=0;
- truncate t_target;
- insert into t_target
- select
- item_id, created_time, modified_time, item_name, other
- from
- (
- select
- t0 . *,
- if(@a = created_time and @b = item_name, @f:=0, @f:=1) f,
- @a:=created_time,
- @b:=item_name
- from
- (
- select
- *
- from
- t_source
- order by created_time , item_name
- ) t0
- ) t1
- where
- f = 1;
- commit;
执行计划如下:
![](https://www.aqdb.cn/uploadfile/0d/6468e5d8.jpg)
以上都是没有添加任何索引的情况.
添加索引如下:
create index idx_sort on t_source(created_time,item_name,item_id);
analyze table t_source;
创建索引之后,
使用表连接查询方式耗时11s,小幅提升.
使用MySQL特性的方式,耗时11-12s,反而更慢.
使用MySQL自定义变量的方式,耗时还是18s.
很显然,MySQL自定义变量的方式,其实没有利用索引.
最终改进SQL
- set @a:='0000-00-00 00:00:00';
- set @b:=' ';
- truncate t_target;
- insert into t_target
- select * from t_source force index (idx_sort)
- where (@a!=created_time or @b!=item_name) and (@a:=created_time) is not null and (@b:=item_name) is not null
- order by created_time,item_name;
- commit;
耗时11s.
该语句具有以下特点。
(1)消除了嵌套子查询,只需要对t_source表进行一次全索引扫描,查询计划已达最优。
(2)无需distinct二次查重。
(3)变量判断与赋值只出现在where子句中。
(4)利用索引消除了filesort。
强制通过索引idx_sort查找数据行 -> 应用where筛选器 -> 处理select列表 -> 应用order by子句。
为了使变量能够按照created_time和item_name的排序顺序进行赋值和比较,必须按照索引顺序查找数据行。这里的force index (idx_sort)提示就起到了这个作用,必须这样写才能使整条查重语句成立。否则,因为先扫描表才处理排序,因此不能保证变量赋值的顺序,也就不能确保查询结果的正确性。order by子句同样不可忽略,否则即使有force index提示,MySQL也会使用全表扫描而不是全索引扫描,从而使结果错误。
索引同时保证了created_time,item_name的顺序,避免了文件排序。force index (idx_sort)提示和order by子句缺一不可,索引idx_sort在这里可谓恰到好处、一举两得。
查询语句开始前,先给变量初始化为数据中不可能出现的值,然后进入where子句从左向右判断。先比较变量和字段的值,再将本行created_time和item_name的值赋给变量,按created_time,item_name的顺序逐行处理。item_name是字符串类型,(@b:=item_name)不是有效的布尔表达式,因此要写成(@b:=item_name) is not null。
"insert into t_target select * from t_source group by created_time,item_name;"的写法,它受"sql_mode='ONLY_FULL_GROUP_BY'"的限制。
运行耗时和原文有出入,可能是因为我的环境是SSD的缘故.
另外,避免回表的开销,可以增加索引的字段
drop index idx_sort on t_source;
create index idx_sort on t_source(created_time,item_name,item_id,modified_time,other);
analyze table t_source;
使用上述索引,终极改进的SQL 耗时可以降到 9.5s
参考:
http://blog.csdn.net/wzy0623/article/details/54378367
http://blog.csdn.net/wzy0623/article/details/54378575
索引
变量
子句
方式
顺序
查询
数据
语句
处理
排序
提示
字段
特性
环境
结果
保证
应用
极致
有效
省时
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
重启服务器有什么危害
数据库服务器如何加载索引的
万兴科技是互联网高科技吗
2008数据库怎么打安全性
口碑好云主机服务器商家
南阳手机app软件开发价格
软件开发试点
河南科技大学互联网加文件
中小企业网络安全风险
数据库方向工作内容
计算机网络技术学哪些课程
郑州交友软件开发哪家专业
宽带网络技术前景
华为服务器怎么把千兆口改成百兆
上海掌玩网络技术有限公司
厦门武夷山软件开发
静安区个人数据库服务商报价行情
奥维地图可用的服务器地址
我的世界服务器开商店
下一代科技互联网发展趋势
软件开发是否需要先注册
陕西党员教育软件开发电话
静态服务器下载安全
软件开发购销清单
mysql数据库1067
维护网络安全,注重舆论引导
ios 删除数据库
常用软件开发优缺点
短视频服务器哪个最好
服务器消耗品