比如现在有一张user表,表结构及数据如下:


现在想根据创建时间升序查询user表,并且分页查询,每页2条,那很容易写出sql为:
select * from user order by create_time limit pageNo,2;
1、查询第一页数据时:

2、查询第四页数据时:

user表共有8条数据,有4页数据,但是实际查询过程中第一页与第四页竟然出现了相同的数据。
这是什么情况?难道上面的分页SQL不是先将两个表关联查询出来,然后再排好序,再取对应分页的数据吗???

这里我们查看下对应SQL的执行计划:

可以确认是用的文件排序,表确实也没有加额外的索引。所以我们可以确定这个SQL执行时是会找到limit要求的行后立马返回查询结果的。
不过就算它立马返回,为什么分页会不准呢?
官方文档里面做了如下说明:

如果order by的字段有多个行都有相同的值,mysql是会随机的顺序返回查询结果的,具体依赖对应的执行计划。也就是说如果排序的列是无序的,那么排序的结果行的顺序也是不确定的。
那这种情况应该怎么解决呢?
官方给出了解决方案:

如果想在Limit存在或不存在的情况下,都保证排序结果相同,可以额外加一个排序条件。例如id字段是唯一的,可以考虑在排序字段中额外加个id排序去确保顺序稳定。
作者:丘八老爷
blog.youkuaiyun.com/qiubabin/article/details/70135556
本文探讨了MySQL中使用orderby和limit进行排序和分页时遇到的问题,特别是在排序字段存在重复值时,可能导致分页数据不准确的情况。通过分析SQL执行计划和官方文档,揭示了问题的根本原因,并提供了解决方案。
2558

被折叠的 条评论
为什么被折叠?



