3

MySQL分页时使用limit+order by会出现数据重复解决方法

 2 years ago
source link: https://www.huhexian.com/33076.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

MySQL分页时使用limit+order by会出现数据重复解决方法

2022-03-2110:22:01评论933字

先说下现象,MySQL分页时使用limit+order by会出现数据重复,在第一个页里面出现了"三只松鼠",然后在第二页里面还有“三只松鼠”。

第一页sql:

  1. SELECT * FROM `client_good_classifylist` WHERE ( 1=1 and clientkeynum='83D965C149CC5C9BA793896B389E8FBD' and is_del=1 ) ORDER BY `o` ASC LIMIT 0,10
MySQL分页时使用limit+order by会出现数据重复解决方法第二页sql:
  1. SELECT * FROM `client_good_classifylist` WHERE ( 1=1 and clientkeynum='83D965C149CC5C9BA793896B389E8FBD' and is_del=1 ) ORDER BY `o` ASC LIMIT 10,10
MySQL分页时使用limit+order by会出现数据重复解决方法排序号字段o是int类型,当排序号o的值都是一样的,我的数据都是0的时候,出现了这样的情况。

问题分析

在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版本之后才出现了这种情况。

解决办法

后面加一个辅助排序字段,形成排序组合,为了保证辅助字段值不重复我使用自增id。

  1. $list = Db::table('client_good_classifylist')
  2. ->where($where)
  3. ->order("o", "asc")
  4. ->order("id", "desc")
  5. ->limit($offset . ',' . $pagesize)
  6. ->select();

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK