MySQL 5.6 排序数据丢失的诡异现象

2018-06-25 21:35:14 +08:00
 stevenkang

按照第一条的 SQL 查询 4 条数据,ID 分别为 3、2、4、1

然后按照第 2、3 条 SQL 进行同样的排序条件以及分页查询,预期的结果应该是 3、2 和 4、1

但是执行结果如下

ID 为 2 的数据竟然不见了,目前暂时通过 date desc, id desc 两个组合排序解决了此问题,但是又带来了新的问题,这样排序会导致索引实效。

有其他小伙伴遇到此类情况了吗?欢迎分享解决方案。

4822 次点击
所在节点    MySQL
12 条回复
GTim
2018-06-25 21:40:14 +08:00
楼主这是什么软件,语法高亮好有感觉

我猜呢,就是字段类型的问题,请注意 2 4 条数据的 date1 是一样,查询不保证返回顺序
GTim
2018-06-25 21:49:42 +08:00
解决办法吗?如果你不想用数据库多字段排序,反正每页也才几十条数据而已,先读出来再排一次序

好像,不知道,谁说的,有一条数据库铁律,就是任何非必要计算,都在应用层解决,而非数据库层解决
thread2
2018-06-25 21:58:18 +08:00
// LIMIT clause results in duplicate data across pages
https://bugs.mysql.com/bug.php?id=69732
Troevil
2018-06-25 22:02:37 +08:00
因为不稳定, 唯一排序字段 date1 出现一样的值,order by 不能确定就会出现顺序错乱 不同的机器,不同时间去执行都有可能出现不同的结果,解决方法就是让 order by 能够确定顺序 比如:order by date1,id
mingyun
2018-06-25 22:04:33 +08:00
貌似没什么办法,之前在阿里云论坛看到这个问题
yangqi
2018-06-25 22:10:40 +08:00
mysql select 是随机的。你这个 date1 相同,排序再加 Limit 就随机选择了。需要再加上 id 排序即可解决
stevenkang
2018-06-25 23:22:55 +08:00
@GTim 软件是 navicat for mysql。数据量少的情况下确实可以用应用层来解决,这里数据比较多。

@Troevil asc 排序没有这个问题。如果 order by 两个字段的话,会导致索引失效,这里比较麻烦。
@thread2 看来这个 BUG 一直在呀,只有用别的办法解决了

@yangqi 现在解决方案就是 date + id 一起排序,唯一缺点是会导致索引失效,真是蛋疼啊。
aaronly
2018-06-25 23:31:42 +08:00
不只是 mysql, 排序算法本身存在不稳定性, 提高稳定性的方法就是增加比较关键字
参考: https://en.wikipedia.org/wiki/Sorting_algorithm 章节:stability
yangqi
2018-06-25 23:44:19 +08:00
@stevenkang 这个很简答,再加一个索引不就行了,keyname (date, id) 或者 kename (date desc, id asc)
mooncakejs
2018-06-26 00:14:04 +08:00
索引可以复合解决
ryuzaki113
2018-06-26 08:12:52 +08:00
order by id
Ravenddd
2018-06-26 09:59:28 +08:00
limit 是根据行的序号去操作的, 当 order by 的字段存在重复的时候, 行数就会随机排序, 这时候用 limit 就会根据随机的行序号拿, 分页自然也会出现少了数据的假象, 加上主键排序这个问题就可以解决, 要保证排序的组合必定唯一
索引的话楼上的说了, 复合索引可以的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/465794

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX