您当前的位置:首页 > 电脑百科 > 数据库 > MYSQL

MySQL中Order by 结合 Limit 使用时的潜在陷阱

时间:2019-09-09 13:07:25  来源:  作者:

MySQL中Order by 结合 Limit 使用时的潜在陷阱

 

如上,我们在MySQL 中常用 order by 来进行排序,再结合使用 limit 来实现数据的分页获取,然而这种写法却隐藏着较深的使用陷阱——在排序字段有数据重复的情况下,可能出现排序结果与预期不一致的问题,即分页查询数据时,不同分页之间存在相同的数据。

接下来我们详细描述一下这个陷阱及解决方案。


问题复盘

我们通过三步重现一下这个问题:

  1. 根据age升序取前20条(ORDER BY + LIMIT 20)
  2. 根据age升序取前10 条,第一页(ORDER BY + LIMIT 10)
  3. 根据age升序取前10~20条,第二页(ORDER BY + LIMIT 10,20)

首先,使用 order by 对age进行排序,通过 limit 限制返回前20条记录,SQL如下。

MySQL中Order by 结合 Limit 使用时的潜在陷阱

 

查询结果如下:

MySQL中Order by 结合 Limit 使用时的潜在陷阱

 


然后,同样使用 order by 对age进行排序,通过 limit 限制返回前10条记录,作为第一页数据,SQL如下:

MySQL中Order by 结合 Limit 使用时的潜在陷阱

 

查询结果如下,我们上一步比较一下,发现前10条记录竟然存在不一样的地方,如下绿框中数据,在上一步的limit20结果中并不属于前10条。

MySQL中Order by 结合 Limit 使用时的潜在陷阱

 


最后,同样使用 order by 对 age 进行排序,通过 limit 限制返回前第11~20条记录,作为第二页数据,SQL如下:

MySQL中Order by 结合 Limit 使用时的潜在陷阱

 

查询结果如下,我们也同样发现了存在于 limit 10 里面的记录,如黄色框。

MySQL中Order by 结合 Limit 使用时的潜在陷阱

 

分析上面的数据,出现重复的数据项存在一个比较明显的特征,那就是他们的排序字段(age)值相同。也就是说,order by查询与limit 只保证排序字段不同的其结果集时是绝对有序的,排序值相同的结果不保证其顺序的一致性,MySQL是会随机的顺序返回查询结果的,具体依赖对应的执行计划。


求证MySQL参考手册

在 MySQL5.7参考手册的 LIMIT Query Optimization 章节中提到:

If you combine LIMIT row_count with ORDER BY, MySQL stops sorting as soon as it has found the first row_count rows of the sorted result, rather than sorting the entire result. If ordering is done by using an index, this is very fast. If a filesort must be done, all rows that match the query without the LIMIT clause are selected, and most or all of them are sorted, before the first row_count are found. After the initial rows have been found, MySQL does not sort any remainder of the result set.

One manifestation of this behavior is that an ORDER BY query with and without LIMIT may return rows in different order, as described later in this section.

若将 order by 与 limit row_count 一起使用,MySQL会在找排序结果中的第一个“第N条记录” 时就停止,而不是对整个结果进行排序。如果使用索引进行排序,那么这个操作就会非常快。如果必须要通过文件排序,所有符合查询条件的记录都将被选中,并且所有的数据都将被排序,直到第一个 “第N条记录” 被找到。在第一条的数据都被找到之后,MySQL不会继续把结果中剩余的数据进行排序。

这种实现行为的表现之一就是order by查询在配合 limit 使用 和不配合limit使用的情况下的返回记录,排序情况是不同的。


在 LIMIT Query Optimization 章节中,同时也提到:

If an index is not used for ORDER BY but a LIMIT clause is also present, the optimizer may be able to avoid using a merge file and sort the rows in memory using an in-memory filesort operation. For details, see The In-Memory filesort Algorithm.

如果 order by 不使用索引,同时还存在 limit 子句,优化器可能会使用 filesort 操作对内存中的行进行排序(in-memory sort)。

在 LIMIT Query Optimization章节最后,提供了一个例子,与我们遇到的问题一样。此外,给出解决方案——在order by中指定一个二级排序字段,这个字段需唯一,这样就保证了整个排序结果的有序性,如下:

MySQL中Order by 结合 Limit 使用时的潜在陷阱

 


解决方案

正如 MySQL 参考手册中提到的,在order by 指定的排序字段后,增加加一个二级排序字段,这个字段需要绝对有序,这样就保证了整个排序结果的有序性,接下来我们改写下之前的SQL,如下:

MySQL中Order by 结合 Limit 使用时的潜在陷阱


Tags:MySQL Order by   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
▌简易百科推荐
作者:雷文霆 爱可生华东交付服务部 DBA 成员,主要负责Mysql故障处理及相关技术支持。爱好看书,电影。座右铭,每一个不曾起舞的日子,都是对生命的辜负。 本文来源:原创投稿 *爱可生...【详细内容】
2021-12-24  爱可生    Tags:MySQL   点击:(7)  评论:(0)  加入收藏
生成间隙(gap)锁、临键(next-key)锁的前提条件 是在 RR 隔离级别下。有关Mysql记录锁、间隙(gap)锁、临键锁(next-key)锁的一些理论知识之前有写过,详细内容可以看这篇文章...【详细内容】
2021-12-14  python数据分析    Tags:MySQL记录锁   点击:(18)  评论:(0)  加入收藏
binlog 基本认识 MySQL的二进制日志可以说是MySQL最重要的日志了,它记录了所有的DDL和DML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二...【详细内容】
2021-12-14  linux上的码农    Tags:mysql   点击:(13)  评论:(0)  加入收藏
为查询优化你的查询 大多数的MySQL服务器都开启了查询缓存。这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的。当有很多相同的查询被执行了多次的时候,这些查...【详细内容】
2021-12-09  元宇宙iwemeta    Tags:mysql   点击:(15)  评论:(0)  加入收藏
测试的目的和原因,公司有很多程序员,每个程序员对数据库和表结构都有自己的理解。而且每个程序员的理解往往是以效率考虑。既然都是为了效率考虑,那么我就来测试一下究竟哪种使...【详细内容】
2021-12-08  吴彬的分享    Tags:Mysql数据库   点击:(14)  评论:(0)  加入收藏
当你们考虑项目并发的时候,我在部署环境,当你们在纠结使用ArrayList还是LinkedArrayList的时候,我还是在部署环境。所以啊,技术不止境,我在部环境。今天这篇文章缕一下在同一台服...【详细内容】
2021-12-08  秃头码哥    Tags:MySQL数据库   点击:(17)  评论:(0)  加入收藏
对于数据分析来说,MySQL使用最多的是查询,比如对数据进行排序、分组、去重、汇总及字符串匹配等,如果查询的数据涉及多个表,还需要要对表进行连接,本文就来说说MySQL中常用的查询...【详细内容】
2021-12-06  笨鸟学数据分析    Tags:MySQL   点击:(21)  评论:(0)  加入收藏
在学习SQL语句之前,首先需要区分几个概念,我们常说的数据库是指数据库软件,例如MySQL、Oracle、SQL Server等,而本文提到的数据库是指数据库软件中的一个个用于存储数据的容器。...【详细内容】
2021-11-24  笨鸟学数据分析    Tags:SQL语句   点击:(23)  评论:(0)  加入收藏
概述以前参加过一个库存系统,由于其业务复杂性,搞了很多个应用来支撑。这样的话一份库存数据就有可能同时有多个应用来修改库存数据。比如说,有定时任务域xx.cron,和SystemA域...【详细内容】
2021-11-05  Java云海    Tags:分布式锁   点击:(31)  评论:(0)  加入收藏
MySQL的进阶查询 一、 按关键字排序 使用ORDERBY语句来实现排序排序可针对一个或多个字段ASC:升序,默认排序方式 【升序是从小到大】DESC:降序 【降序是从大到小】ORDER BY的...【详细内容】
2021-11-05  Java热点    Tags:SQL语句   点击:(28)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条