mysql 多行排序字段一样结果不稳定
嘻嘻发布于2022-09-05
浏览最近在做一个线上的排序需要用到数据的创建时间,但是因为数据都是之前一次性导入的,都是相同的,导致排序出现不稳定的情况,表现是页面的数据会重复出现,但是在mysql数据库中只有一条记录。
原因
上面问题导致的原因是创建时间都是一样的,根据mysql官方的解释:
如果多个行在ORDER BY列中具有相同的值,则服务器可以自由地以任何顺序返回这些行,并且可以根据总体执行计划以不同的方式返回这些行。换句话说,这些行的排序顺序相对于非排序列是不确定的。
方法
针对上面这个问题有两种解决方式:
- 排序的字段保证不会线下大量数据行都是一样的,但这个不一定能保证;
- 在使用这个字段排序的基础上,新增一个排序字段;
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标准所要求的, 但最后的结果不一样,所以一定要注意。