代码编织梦想

mysql5.7之前确实可以select * from (select * from table_a order by filed_a desc ) a group by a.filed_b这种写法去重,但是5.7之后,group by 内部优化,只要执行group by,都会重新按照主键的顺序重新排序,再去重,导致如果有遇到去重需要取最新的那条记录的需求一直是有问题的,这个问题我总结了3种方法来解决。

方法1:limit

执行limit后,用explain查看发现会多执行一个DERIVED,不要小瞧它,正是因为他,会让我们之前的先排序再去重可以没有问题的实现,说实话原理上并没有搞的很清楚,有时间可以研究下DERIVED吧

select * from (select * from table_a order by filed_a desc limit 100000000) a group by a.filed_b

方法2:双重group by

其实说白了还是为了让sql执行先执行下DERIVED,再去重才能成功,写法如下

select * from (select * from table_a group by id order by filed_a desc) a group by a.filed_b

 

上述两种方法虽然实现了业务功能,但是你会发现数据量大,其他条件多的情况下,SQL性能差的一逼,条件一多,越来越慢,越来越差。

方法3:代码实现排序去重,SQL只做查询

因为我是做java的,所以代码是java,其实思路有的话,代码实现起来是很方便的,这里用的是lambda表达式

list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparingLong(Object::getXXXId))), ArrayList::new));

这个lambda表达式实现的是去重,只需要我们将查询的数据排序后放进去,去重后,再从list拿到主键list<Long> ids,我们可以把ids当做条件放到sql中,当做参数,原始sql只需要这样既可

select * from table_a where id in(id1,id2,id3) order by filed_a desc

改完之后会发现性能高了会不止一倍,毕竟sql已经变得很简单,但是如果数据多的话,这种方法还是存在问题的,毕竟内存中做去重,数据量大的话,容易内存溢出,而且sql条件会极多,不利于查询

所以如果去重的数据少的话,建议用第三种方法,否则也只能在第一种或者第二种或者其他方法上做文章了,但是性能始终会是到坎。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_16207635/article/details/88688076

去重排序----MySQL-爱代码爱编程

一-去重后,按照汉字的拼音首字母顺序排,英文和数字在前 select DISTINCT t.name from ymw_goods t order by convert(t.name using gbk) collate gbk_chinese_ci; 二----去重后,按最新的时间顺序来拍 1:最简单,且字段全部相同,排除其他字段不同;  先对表

Lambda对数据实现多线程、分组、去重、排序、求和、过滤、集合拷贝-爱代码爱编程

一、数据准备(建立一个User对象) //此处节省空间省略get/set方法以及包名 public class User { private Long id; //姓名 private String name; //年龄 private int age; //性别 private St

mysql 先排序再去重_sql如何先排序再去重-爱代码爱编程

场景 有一张得分表(score),记录了用户每次的得分,同一个人可能有多个得分。 id name score 1 tom 45 2 jack 78 3 tom 34 . . . 需求:找出分数最高的前5个人。 SQL1 首先我们写个最简单的sql: select id, name, score from s

mysql 先排序再去重,Mysql DISTINCT问题-爱代码爱编程

问题描述 因为要设计一个数据库表,进行一个倒序去重的操作。 例如: id Name 1 B 2 A 3 A 4 C 5 C 6 B 场景:例如说我们需要得到一个用户的搜索记录,那么肯定不会仅仅根据时间倒序排序给出列表展示,因为这样会出现重复的问题。我们需要去重,并且保证用户对一个搜索记录是按照最后一次搜索操作的时间排序

mysql去重获取最新的一条数据_不懂bug的博客-爱代码爱编程

举例 看数据 这里的业务场景是 用户id为434 在公司id为 234中,存在多条入职离职记录,但实际场景中只想获取该用户最新的一条数据信息,该如何获取呢? 第一种解决方法 子查询分组排序SELECT a.user_id, a.company_id, a.create_time FROM ( SELECT user_id,company_id

mysql-组分去重/排序-不同版本实现row_number()_至子星的博客-爱代码爱编程

一、 使用场景 在数据有重复情况下,取ID最大或者最小的数据按照某个规则取提取数据行,比如需要分组排序后取topN数据。最简单的一个例子就比如提取一个班级不同科目排名前3同学的信息。下面以此为例进行mysql-5.7与mysql-8.0分析(5.7和8.0差异性比较大)。二、创建模拟数据 DROP TABLE IF EXISTS `class_scor

mysql多表联查,查询结果出现重复的原因和解决方法-爱代码爱编程

1 背景 根据业务需要,需要使用如下的命令进行多表联查 select a.id as a_id, b.id as b_id, b.protocol as protocol, b.priority as priority

mysql 先排序在去重_使用mysqllambdaquerywrapper 来实现先排序后去重-爱代码爱编程

之前遇到个问题就是如何把排序的优先级放在去重前 常规写法 #这种写法直接会导致 order by 失效,因为group by 的排序比order by优先级要高 select * from a表 order by in