问题
在不select * 的 前提下 ,用
SELECT id,created_at FROM medicinal_materials_info
ORDER BY created_at DESC LIMIT 0,10
和
SELECT id,created_at FROM medicinal_materials_info
ORDER BY created_at DESC LIMIT 10,10
进行两次sql查询,得到的结果可能出现相同数据.
原因
在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版本之后才出现了这种情况
解决办法
1. 全量查询 用select * 代替
2. order by 中增加索引项的排序
3. 排序项上加上索引