转自: https://blog.csdn.net/tsxw24/article/details/44994835

我经常使用order by和limit来做数据分页显示并排序,一直也没发现过什么问题。但这两天缺遇到一个严重的问题,在按时间戳升序排列并用limit分批读取数据时,却发现在某些记录丢失了,表中明明有的记录确死活读取不到。研究了大半天终于发现了问题所在,记录一下以防忘记,也是给大家提个醒。

问题重现

工具和原料

数据库:

Ver 14.14 Distrib 5.6.11, for Linux (x86_64) using EditLine wrapper

表结构:

字段 类型 说明
id int(10) 主键
pay_time int(10) 时间戳,有索引
flag tinyint(1) 类型标识,用于分类筛选

数据

大概5000条数据, 大部分记录的flag都等于0,pay_time字段时间戳格式都正确

需求

筛选出flag=0的记录,按pay_time升序依次读取所有数据。

处理方式

使用limit分批读取数据,如: 
select id, pay_time from order_customer_new where flag=0 order by pay_time asc, id asc limit 250, 10;

发现问题

在读取数据的过程中,发现有时间戳相等的记录,分两次读取出来时,可能会丢失一条记录。见下图,id=465的记录就丢失了。

问题分析与猜测

当排序值相等,其先后顺序的不确定的。这里我猜想:当465和466处于limit末尾时466排在前面,而当处于limit开头时,466缺排到后面去了。所以465丢失了,466出现了两次。 
排序值相等时,其顺序的不确定应该是其结果不可预测。但真正进行排序时应该会采取一定的规则以确定唯一的排序结果,也就是说,即使有相等的排序值,多次排序的结果应该是一样的。从以前的使用经历看,mysql是这么做的。但这次遇到的问题似乎说明mysql并不是这样的。不知道mysql本来就是如此,还是一个bug。

解决办法

既然猜想此问题是因为排序值相等造成顺序不确定引起的,那么就试试增加排序条件让其排序结果是确定的、唯一的。一试果然OK,如下图所示,465出来了。

请求支援

我对mysql的底层实现和数据库原理不是很了解,完全不明白mysql为什么会出现这种问题。若哪位朋友能解释一二,不胜感激!

mysql同时使用order by和limit查询时的一个严重隐患 -- 丢失数据的更多相关文章

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

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

  2. 采坑笔记——mysql的order by和limit排序问题

    背景说明 今天写出一个十分弱智的bug,记录一下,提醒自己以后别这种犯错,不怕丢人哈~ 在写一个分页查询记录的sql时,要根据添加的时间逆序分页输出,之前的写法是酱紫 select record.a, ...

  3. mysql实现in子句的limit查询 (转)

    在supesite里面执行一个SQL语句: select * from supe_spaceitems where catid=98 and itemid not in(select itemid f ...

  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通过“延迟关联”进行limit分页查询优化的一个实例

    最近在生产上遇见一个分页查询特别慢的问题,数据量大概有200万的样子,翻到最后一页性能很低,差不多得有4秒的样子才能出来整个页面,需要进行查询优化. 第一步,找到执行慢的sql,如下: SELECT  ...

  7. Mybatis一对多/多对多查询时只查出了一条数据

    问题描述: 如果三表(包括了关系表)级联查询,主表和明细表的主键都是id的话,明细表的多条数据只能查询出来第一条/最后一条数据. 三个表,权限表(Permission),权限组表(Permission ...

  8. Mybatis 级联查询时只查出了一条数据

    造成这个问题的原因是: 主表和明细表的id字段名相同造成的. 问题的关键在于resultMap中如果不定义类似主键之类的能够区分每一条结果集的字段的话,会引起后面一条数据覆盖前面一条数据的现象.

  9. oracle中使用sql查询时字段为空则赋值默认

    转至:http://www.th7.cn/db/Oracle/201501/86125.shtml oracle 通过 nvl( )函数sql 查询时为 空值 赋默认值 oracle 函数介绍之nvl ...

随机推荐

  1. Linux_(1)基本命令(上)

    一.基本命令1.我是谁 whoami --who am i2.谁在线 who w3.显示当前路径(定位) pwd4.切换目录 cd ~返回主目录 cd ..返回上一级目录5.查看某个目录中的子目录和文 ...

  2. GitHub上Markdown语法的高级应用

    高级语法格式 本篇的内容来源于Github使用高级格式写作.如果在观看时有什么问题,可以直接查阅源文件.另外需要说明的是Git对Markdown的支持增加了一些扩展功能,因此在Git上可以渲染的Mar ...

  3. hdu 1010(DFS) 骨头的诱惑

    http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目大意从S出发,问能否在时间t的时候到达终点D,X为障碍 需要注意的是要恰好在t时刻到达,而不是在t时间 ...

  4. linux使用笔记4

    运行已经安装好的软件: cd到这个软件的安装目录 输入命令/:./软件名称 就可以了 运行geoserver 1.首先需要添加JAVA_HOME的环境变量: 在服务器没有设置JAVA_HOME的情况下 ...

  5. BZOJ1093或洛谷2272 [ZJOI2007]最大半连通子图

    BZOJ原题链接 洛谷原题链接 和 Going from u to v or from v to u?(题解)这道题类似,只不过是求最大子图的大小和个数而已. 一样用\(tarjan\)求强连通分量, ...

  6. iOS通过URL构建UIImage

    很多时候我们只能得到一个URL,然后需要构建一个UIImage. 通常情况下,我们一般都是通过SDWebImage来直接构建UIImageVIew的image,如何用URL直接构建UIImage呢? ...

  7. Vim中如何使用正则进行搜索

    #set magic这句的作用在于将vim的正则打开. 这样就可以搜索了. 至于正则的相关的内容.在此抄一份.以免于下次自己还要去百度. 符号 匹配 . (dot) 任意单一字符 \d 任意一位数字 ...

  8. 【原创】DOTNET动态调试破解Spoon,及MSI安装包文件替换技术

    提到Spoon可能大家还会感到陌生,但是如果提及XenoCode那么研究过DOTNET的人应该都知道吧.Spoon的前身就是XenoCode,虽然没有了PostBuild这个混淆软件,但是虚拟化技术仍 ...

  9. linux以16进制方式查看文件

    vim打开文件 :%!xxd  以16进制查看 :%!xxd -r  转回来

  10. Python编程笔记(第三篇)【补充】三元运算、文件处理、检测文件编码、递归、斐波那契数列、名称空间、作用域、生成器

    一.三元运算 三元运算又称三目运算,是对简单的条件语句的简写,如: 简单条件处理: if 条件成立: val = 1 else: val = 2 改成三元运算 val = 1 if 条件成立 else ...