mysql同时使用order by和limit查询时的一个严重隐患 -- 丢失数据
转自: 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查询时的一个严重隐患 -- 丢失数据的更多相关文章
- MySQL中ORDER BY与LIMIT一起使用(有坑)
1. 现象与问题 ORDER BY排序后,用LIMIT取前几条,发现返回的结果集的顺序与预期的不一样 下面是我遇到的问题: 可以看到,带LIMIT与不带LIMIT的结果与我预期的不一样,而且“很不可 ...
- 采坑笔记——mysql的order by和limit排序问题
背景说明 今天写出一个十分弱智的bug,记录一下,提醒自己以后别这种犯错,不怕丢人哈~ 在写一个分页查询记录的sql时,要根据添加的时间逆序分页输出,之前的写法是酱紫 select record.a, ...
- mysql实现in子句的limit查询 (转)
在supesite里面执行一个SQL语句: select * from supe_spaceitems where catid=98 and itemid not in(select itemid f ...
- MySQL中 order by 与 limit 的执行顺序以及使用实例
在 MySQL 执行查询的时候,我们可能既要对结果集进行排序又要限制行数,那么此时 order by 与 limit 的执行顺序是怎么样的呢? order by与limit的执行顺序是:先执行orde ...
- MySQL中 ORDER BY 与 LIMIT 的执行顺序
如下: ORDER BY 与 LIMIT 的执行顺序:ORDER BY > LIMIT ORDER BY 与 LIMIT 的编写顺序:ORDER BY > LIMIT 正确写法: sele ...
- mysql通过“延迟关联”进行limit分页查询优化的一个实例
最近在生产上遇见一个分页查询特别慢的问题,数据量大概有200万的样子,翻到最后一页性能很低,差不多得有4秒的样子才能出来整个页面,需要进行查询优化. 第一步,找到执行慢的sql,如下: SELECT ...
- Mybatis一对多/多对多查询时只查出了一条数据
问题描述: 如果三表(包括了关系表)级联查询,主表和明细表的主键都是id的话,明细表的多条数据只能查询出来第一条/最后一条数据. 三个表,权限表(Permission),权限组表(Permission ...
- Mybatis 级联查询时只查出了一条数据
造成这个问题的原因是: 主表和明细表的id字段名相同造成的. 问题的关键在于resultMap中如果不定义类似主键之类的能够区分每一条结果集的字段的话,会引起后面一条数据覆盖前面一条数据的现象.
- oracle中使用sql查询时字段为空则赋值默认
转至:http://www.th7.cn/db/Oracle/201501/86125.shtml oracle 通过 nvl( )函数sql 查询时为 空值 赋默认值 oracle 函数介绍之nvl ...
随机推荐
- 转换 transform
转换 定义: 1.转换是使元素改变形状.尺寸和位置的一种效果 2.又称为变形,即,可以向元素应用 2D 或 3D 转换,从而对元素进行旋转.缩放.移动或倾斜 3.2D转换:使元素在 X 轴和 Y 轴平 ...
- windows2003两台服务器,局域网之间不能互相访问
准备在两台服务器之间,映射网络驱动器,但怎么也连不上了. 可以在网络邻居中看到对方的机器,但就是访问不到共享的文件,也无法做网络映射. 搜索了一下,发现在是因为防火墙中,没有把"文件和打印机 ...
- CH#17C 舞动的夜晚
原题链接 即求二分图的不可行边数量,因为不保证是完备匹配,所以需要通过网络流求出任意一组最大匹配,并建立新图判断. 建新图:对于跑完网络流的图上已经匹配的边,建立反边:对于没有匹配的边,建立正边(图只 ...
- iOS常用代码总结
1.读取图片NSString *path = [[NSBundle mainBundle] pathForResource"icon" ofType"png"] ...
- Spring MVC 中的 forward redirect Flash属性
forward:转发 redirect:重定向 -- 转发比重定向快,因为重定向经过客户端,而转发并没有. -- 重定向能够重定向到一个外部网站,但转发不行. -- 重定向能够避免在用户重新加载页面时 ...
- 【UI测试】--独特性
- python3版本main.py执行产生中间__pycache__详解
__pycache__ 用python编写好一个工程,在第一次运行后,总会发现工程根目录下生成了一个__pycache__文件夹,里面是和py文件同名的各种 *.pyc 或者 *.pyo 文件. 先大 ...
- 2017/2/6:在oracle中varchar与varchar2的区别与增删改查
1.varchar2把所有字符都占两字节处理(一般情况下),varchar只对汉字和全角等字符占两字节,数字,英文字符等都是一个字节:2.VARCHAR2把空串等同于null处理,而varchar仍按 ...
- MathExam
MathExam 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 575 605 • Est ...
- rpm安装jdk7
原文:http://www.centoscn.com/image-text/config/2015/0208/4658.html 系统环境:centos-6.5 安装方式:rpm安装 软件:jdk-7 ...