背景说明

今天写出一个十分弱智的bug,记录一下,提醒自己以后别这种犯错,不怕丢人哈~

在写一个分页查询记录的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出来的结果应该也是逆序的,但结果却很打脸,是正序的。

分析原因

  1. 首先控制变量,代码回滚到之前,把后来加的各种逻辑都去掉,还原到上述sql,只把limit 0,10移到最后,发现timestamp是正序的,那么问题应该就出在这里了,与后来加的其他逻辑没有关系。
  2. 那么再试一下删掉limit操作,结果timestamp是无序的!这不可能啊,于是认真看了下数据,发现一些规律,可能是按y表的自增id或created_at时间字段排序的(因为这两个字段是索引字段),那么到这里,我们至少可以得到一个简单的结论,就是联表查询结果,不是按照嵌套查询中的order by排序的,现在正向一看,确实不可能按这个排序,因为括号里面的逻辑对括号外是不可见的。
  3. 还有个问题,上述去掉limit后,最终不是按left join主表的顺序输出,按照我们常理想象,mysql是循环主表的记录去关联另一张表,那么输出的顺序应该还是主表的顺序啊,但结果却是按另一张表的字段排序的,这又是为什么呢?

    去官方手册中找找线索,发现order by模块中有这么一句话。



    再去limit模块中看一下



    从以上两个截图中,我们可以发现一些端倪,limit操作会对查询有一些优化,查询到指定条数的数据,就可以提前结束了,比如我们本文中的left操作,拿到10条结果就结束查询线程,返回客户端。我猜测,如果没有limit操作,反正全部都要join,可能mysql会对循环逻辑做一些优化,不一定要按主表来循环,思想类似于java编译中的重排序,也对应了上面截图中的那句话。

解决方案

采用最简单、最粗暴的方式,直接把order by 和 limit操作放到最外面就ok啦,其实效率上并没有什么降低,只要索引建的合理即可。

采坑笔记——mysql的order by和limit排序问题的更多相关文章

  1. 从源码看Spring Security之采坑笔记(Spring Boot篇)

    一:唠嗑 鼓捣了两天的Spring Security,踩了不少坑.如果你在学Spring Security,恰好又是使用的Spring Boot,那么给我点个赞吧!这篇博客将会让你了解Spring S ...

  2. MySQL中ORDER BY与LIMIT一起使用(有坑)

    1.  现象与问题 ORDER BY排序后,用LIMIT取前几条,发现返回的结果集的顺序与预期的不一样 下面是我遇到的问题: 可以看到,带LIMIT与不带LIMIT的结果与我预期的不一样,而且“很不可 ...

  3. mysql同时使用order by和limit查询时的一个严重隐患 -- 丢失数据

    转自: https://blog.csdn.net/tsxw24/article/details/44994835 我经常使用order by和limit来做数据分页显示并排序,一直也没发现过什么问题 ...

  4. MySQL中 order by 与 limit 的执行顺序以及使用实例

    在 MySQL 执行查询的时候,我们可能既要对结果集进行排序又要限制行数,那么此时 order by 与 limit 的执行顺序是怎么样的呢? order by与limit的执行顺序是:先执行orde ...

  5. MySQL中 ORDER BY 与 LIMIT 的执行顺序

    如下: ORDER BY 与 LIMIT 的执行顺序:ORDER BY > LIMIT ORDER BY 与 LIMIT 的编写顺序:ORDER BY > LIMIT 正确写法: sele ...

  6. mysql采坑笔记

    mysqld --initialize-insecure // 初始化数据 mysql -u root -p // 登录 navicat for mysql 1251错误解决方法 ALTER USER ...

  7. Hibernate各种基本注解及一对一(多)关系映射采坑笔记

    hibernate提供两种方式配置关系映射,一种XMl配置,一种注解.SpringBoot已经自带了hibernate注解方式,我也是特别喜欢使用注解,特此记下常用的知识点. 1.基本注解 @Tabl ...

  8. kafka入门(采坑)笔记

    前言 之前在工作和学习过程中也会有记笔记的习惯,但是没有发布出来,也因最近各方面的瓶颈急需突破和提升,所以还是要很积极的融入大环境大生态中,好废话不多说,说下这次遇到的问题 第一步启动zk 根据教程安 ...

  9. react采坑笔记

    1. dva + antd input设置defaultVaule时查看时inpu有值但是页面上不显示 解决办法 设置一个key值,当key值改变从新渲染 <div key={this.prop ...

随机推荐

  1. java Redis工具类

    redis就是一个nosql数据库,做存储做缓存的,java代码中就是嵌入了一个客户端,读取与存储数据而已. 先来一个简单的工具类: package com.ming.redis; import re ...

  2. 如何使用rem单位

    最近搞移动端,真是被rem.em与px的换算要了老命了,看了不少文档,似乎弄明白了,这不今天用又蒙圈了. 好多文档上老是说用rem就给html设置font-size,用em就给body设置font-s ...

  3. GitKraken使用教程-基础部分(7)

    8.  本地分支和标签 1) 在提交记录区中查看分支状态 提交记录区中每一个分支都位于一个提交记录所在的行中. 从图 2‑1中可以看到,服务器上的master分支停留在整理格式(把这个提交记录记为or ...

  4. jQuery源码浅析2–奇技淫巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  5. css随堂笔记(二)

    css   sub注释 注释不能嵌套 sub生成结构代码快捷 复合选择器 1.后代选择器 语法:选择器1 选择器2 选择器3  { 属性名:属性值 } 2.子代选择器 子代选择器语法: 选择器1> ...

  6. 浅谈position、table-cell、flex-box三种垂直(水平)居中技巧

    一.首先是喜闻乐见的position方法,经典且万能,用法如下: 父元素{ position:relative; } 子元素{ position:absolute; top:50%; left:50% ...

  7. 零基础逆向工程36_Win32_10_互斥体_互斥体与临界区的区别

    1 引言 讲了第二个内核对象,互斥体.前面已经学过一个内核对象,线程.这节讲两个函数,WaitForSingleObject()和WaitForMultipleObjects().因此这两个函数是根据 ...

  8. (四)JavaScript之[break和continue]与[typeof、null、undefined]

    7].break和continue /** * JavaScript 的break和continue语句 * break 跳出switch()语句 * break 用于跳出循环 * continue ...

  9. JSON中不能加注释

    今天犯了一个白痴级的错误,那就是向JSON数据文件中,很多行后面添加注释(Comment,//). 导致Node.js程序不能读取JSON文件,Server启动失败. Debug时间蛮久,经同事提醒才 ...

  10. 【Unity3D学习笔记】解决放大后场景消失不显示问题

    不知道为啥,我的Unity场景放大到一定大小后,就会消失... 解决方案: 选中一个GameObject,然后按F键. F键作用是聚焦,视图将移动,以选中对象为中心.