加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_韶关站长网 (https://www.0751zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

MySQL中 Order By 和 Limit 的排序问题

发布时间:2022-09-17 15:07:11 所属栏目:MySql教程 来源:
导读:  点击上方蓝色“程序猿DD”,选择“设为星标”

  回复“资源”获取独家整理的学习资料!

  作者 |春卷要炸着吃

  来源 |

  在写一个分页查询记录的sql时,
  点击上方蓝色“程序猿DD”,选择“设为星标”
 
  回复“资源”获取独家整理的学习资料!
 
  作者 |春卷要炸着吃
 
  来源 |
 
  在写一个分页查询记录的sql时,要根据添加的时间逆序分页输出,之前的写法是酱紫:
 
  select
  ????record.a,
  ????y.c
  from
  ????(
  ????????select
  ????????????a,b
  ????????from
  ????????????x
  ????????order?by?timestamp?desc
  ????????limit?0,10
  ????)?record
  left?join?y
  on?record.b = y.d;
  因为一些新的需求,要在后面加一些where条件,limit操作不能在嵌套查询里面加了,于是乎把limit 0,10提出来放到最外面,结果order by还留在里面。
 
  当时想嵌套查询出来的record表已经按timestamp字段逆序排列了,再left另一张表,最终再limit出来的结果应该也是逆序的,但结果却很打脸,是正序的。
 
  首先控制变量,代码回滚到之前,把后来加的各种逻辑都去掉,还原到上述sql,只把limit 0,10移到最后,发现timestamp是正序的,那么问题应该就出在这里了,与后来加的其他逻辑没有关系。
 
  那么再试一下删掉limit操作,结果timestamp是无序的!
 
  这不可能啊,于是认真看了下数据,发现一些规律,可能是按y表的自增id或created_at时间字段排序的(因为这两个字段是索引字段),那么到这里,至少可以得到一个简单的结论,就是联表查询结果,不是按照嵌套查询中的order by排序的,现在正向一看,确实不可能按这个排序,因为括号里面的逻辑对括号外是不可见的。
 
  还有个问题,上述去掉limit后,最终不是按left join主表的顺序输出,按照常理想象,mysql是循环主表的记录去关联另一张表,那么输出的顺序应该还是主表的顺序啊,但结果却是按另一张表的字段排序的,这又是为什么呢?
 
  去官方手册中找找线索,发现order by模块中有这么一句话。
  
  再去limit模块中看一下
 
  从以上两个截图中,我们可以发现一些端倪,limit操作会对查询有一些优化,查询到指定条数的数据,就可以提前结束了,比如我们本文中的left操作,拿到10条结果就结束查询线程,返回客户端。
 
  猜测,如果没有limit操作,反正全部都要join,可能mysql会对循环逻辑做一些优化,不一定要按主表来循环mysql排序,思想类似于java编译中的重排序,也对应了上面截图中的那句话。采用最简单、最粗暴的方式,直接把order by 和 limit操作放到最外面就ok啦,其实效率上并没有什么降低,只要索引建的合理即可。
 

(编辑:云计算网_韶关站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!