order by + limit 重复数据

问题描述

最近线上出现了一个问题,在某个 SELECT … FROM table1 ORDER BY ××× LIMIT N 时,第一页和第二页出现了重复的数据。

结论

MySQL在5.6版本的时候对 ORDER BY LIMIT 做了个优化(排序字段无索引,且值不唯一)时,优化器遇到 ORDER BY LIMIT 语句的时候,使用了priority queue(优先队列),优先队列使用的堆排序,因为这种场景是用于求TOP N 问题,堆排快,但是堆排不稳定。

分析

在官方文档当中,有提到
在这里插入图片描述
官方文档当中

while (get_next_sortkey())
     {
       if (using priority queue)
         push sort key into queue
       else
       {
         if (no free space in sort_keys buffers)
         {
           sort sort_keys buffer;
           dump sorted sequence to 'tempfile';
           dump BUFFPEK describing sequence location into 'buffpek_pointers';
         }
         put sort key into 'sort_keys';
       }
     }
     if (sort_keys has some elements && dumped at least once)
       sort-dump-dump as above;
     else
       don't sort, leave sort_keys array to be sorted by caller.

描述了伪代码的优化。原因是啥呢,就是因为快。

PQ

priority queue 是一个堆,order by limit 本质上就是在求TOP N ,那只要求出最大N条数据/最小的N条数据就行。剩下的数据不需要再进行排序,这样就极大的加快了速度。而堆排序总所州市

解决办法

1.索引排序字段
在这里插入图片描述
2.在排序中加上唯一值,比如主键 id,这样由于 id 是唯一的,就能确保参与排序的 key 值不相同。

参考文章:

https://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值