0问题描述在MySQL中,我们通常使用limit进行翻页查询。例如limit(0,10)表示列出第一页10条数据,limit(10,10)表示列出第二页。但是当limit遇到orderby时,可能会出现翻到第二页的时候,第一页的记录又出现了。具体如下:SELECT`post_title`,`post_date`FROMpostWHERE`post_status`='publish'ORDERBYview_countdescLIMIT5,5当使用上面的SQL查询时,很可能是一条与LIMIT0相同的记录,5将出现。而如果用下面的方法,就不会出现重复:SELECT*FROMpostWHEREpost_status='publish'ORDERBYview_countdescLIMIT5,5但是因为post表的字段比较多,我只想用这两个字段,并没有想找出post_content。为了解决这种情况,在ORDERBY后面使用了两个排序条件来解决这个问题,如下:SELECT`post_title`,`post_date`FROMpostWHERE`post_status`='publish'ORDERBYview_countdesc,IDascLIMIT5,5从逻辑上讲,排序MySQL默认使用主键ID作为排序条件,即如果view_count相等,则默认使用主键ID作为排序条件,我们不需要添加IDasc。但事实是,当MySQL混合使用orderby和limit时,会出现排序混乱的情况。1问题分析在MySQL5.6版本中,优化器在遇到orderbylimit语句时,会进行优化,即使用优先级队列。使用优先级队列的目的是排序,当不能使用索引的顺序时使用limitn,那么在排序过程中只需要保留n条记录,虽然这不能解决所有记录的问题排序的开销是需要,但只需要排序缓冲区中的少量内存即可完成排序。MySQL5.6之所以出现第二页数据重复的问题,是因为优先级队列使用了堆排序方式,而堆排序方式是一种不稳定的排序方式,即相同的值可能被排序读出数据顺序不一致。MySQL5.5没有这个优化,所以不会出现这个问题。也就是说,MySQL5.5不存在本文提到的问题,这种情况是在5.6版本之后才出现的。看MySQL解释sql语言时的执行顺序:(1)SELECT(2)DISTINCT
