MySQL分页时使用 limit+order by 会出现数据重复问题
1.先说下现象在第一个页里面出现了"三只松鼠",然后在第二页里面还有“三只松鼠”
第一页sql:
SELECT * FROM `client_good_classifylist` WHERE ( 1=1 and clientkeynum='83D965C149CC5C9BA793896B389E8FBD' and is_del=1 ) ORDER BY `o` ASC LIMIT 0,10
第二页sql:
SELECT * FROM `client_good_classifylist` WHERE ( 1=1 and clientkeynum='83D965C149CC5C9BA793896B389E8FBD' and is_del=1 ) ORDER BY `o` ASC LIMIT 10,10
排序号字段o是int类型,当排序号o的值都是一样的,我的数据都是0的时候,出现了这样的情况。
2.问题分析
在MySQL 5.6的版本上,优化器在遇到order by limit语句的时候,做了一个优化,即 使用了priority queue。
使用 priority queue 的目的,就是在不能使用索引有序性的时候,如果要排序,并且使用了limit n,那么只需要在排序的过程中,保留n条记录即可,这样虽然不能解决所有记录都需要排序的开销,但是只需要 sort buffer 少量的内存就可以完成排序。
之所以MySQL 5.6出现了第二页数据重复的问题,是因为 priority queue 使用了堆排序的排序方法,而堆排序是一个不稳定的排序方法,也就是相同的值可能排序出来的结果和读出来的数据顺序不一致。
MySQL 5.5 没有这个优化,所以也就不会出现这个问题。
也就是说,MySQL 5.5是不存在本文提到的问题的,5.6版本之后才出现了这种情况。
3.解决办法
后面加一个辅助排序字段,形成排序组合,为了保证辅助字段值不重复我使用自增id。
$list = Db::table('client_good_classifylist')
->where($where)
->order("o", "asc")
->order("id", "desc")
->limit($offset . ',' . $pagesize)
->select();
版权声明:若无特殊注明,本文皆为《菜鸟站长》原创,转载请保留文章出处。
本文链接:MySQL分页时使用 limit+order by 会出现数据重复问题 - https://wlphp.com/?post=333