Mysql 排序错乱问题
问题说明
我在系统中设计了一个字段,sort_weight,意为排序比重,当这个值越大,就返回越靠前,默认初始化填充数据的时候,我都是默认传入的0,但是当我接口调用的时候发现,返回的数据并不是预想的,出现了随机和重复,尤其是分页中最为明显;
问题分析
经过谷歌后,我找到了出现该问题的所在。
起初的想法:当order by 的字段相同时,应该是按照表的扫描顺序,返回,让我简单来示例下:
id | name | sort_weight |
---|---|---|
1 | abc | 0 |
2 | test | 0 |
3 | 123 | 0 |
我起初的想法是,数据分页时需要根据数据记录创建时间sort_weight字段倒序,即使用order by sort_weight desc,这时因为sort_weight相同,返回id顺序应该是1,2,3,但是实际上当order by的字段相同的时候 系统对数据的排序可能变得随机,即一会儿这条数据在前面,一会儿这条数据在后面了 ,所以当翻页的时候我们很容易便看到了重复的数据。
后来查阅资料,发现这种现象是“故意”设计的。 如果没有指定ORDER BY语句,则SQL Server(或任何RDBMS)不保证以特定顺序返回结果。 有些人认为,如果没有指定order by子句,行总是以聚簇索引顺序或物理磁盘顺序返回。 然而,这是不正确的,因为在查询处理期间可以改变行顺序的许多因素,例如并行的HASH连接是更改行顺序的操作符的一个很好的例子。
如果指定ORDER BY语句,SQL Server将对行进行排序,并按请求的顺序返回。 但是,如果该顺序不是确定性的,即可能有重复的值,则在每个具有相同值的组中,由于与上述相同的原因,该顺序是“随机的”。
解决办法
确保确定性顺序的唯一方法是在ORDER BY子句中包含保证的唯一列或列组(例如主键)。
6a071fd5-ecf9-50f2-74c1-3df674ec6e2c
本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (CC BY-NC-ND 4.0) 进行许可。