mysql 多行排序字段一样结果不稳定

最近在做一个线上的排序需要用到数据的创建时间,但是因为数据都是之前一次性导入的,都是相同的,导致排序出现不稳定的情况,表现是页面的数据会重复出现,但是在mysql数据库中只有一条记录。

原因

上面问题导致的原因是创建时间都是一样的,根据mysql官方的解释

如果多个行在ORDER BY列中具有相同的值,则服务器可以自由地以任何顺序返回这些行,并且可以根据总体执行计划以不同的方式返回这些行。换句话说,这些行的排序顺序相对于非排序列是不确定的。

方法

针对上面这个问题有两种解决方式:

  1. 排序的字段保证不会线下大量数据行都是一样的,但这个不一定能保证;
  2. 在使用这个字段排序的基础上,新增一个排序字段;
SELECt * FROM orders
ORDER BY create_time, id DESC

说明

影响执行计划的一个因素是limit,因此有limit和无limit的按顺序查询可能返回不同顺序的行。考虑这个查询,它按category列排序,但与id列和评级列不确定:

mysql> SELECT * FROM ratings ORDER BY category;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  3 |        2 |    3.7 |
|  4 |        2 |    3.5 |
|  6 |        2 |    3.5 |
|  2 |        3 |    5.0 |
|  7 |        3 |    2.7 |
+----+----------+--------+

包含limit可能会影响每个类别值内的行顺序。例如,这是一个有效的查询结果:

mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  4 |        2 |    3.5 |
|  3 |        2 |    3.7 |
|  6 |        2 |    3.5 |
+----+----------+--------+

在每种情况下,行都是按列排序的,这是SQL标准所要求的, 但最后的结果不一样,所以一定要注意。

Mysql密码丢失,如何强制改回密码
Redis大key和热key

发表我的评论

电子邮件地址不会被公开。 必填项已用*标注

32 + 24 =

ajax-loader