【MySQL】默认排序不一定是主键排序【原创】

概述

最近出了个bug,有人反馈某个用户的审批记录的排序是乱的,而且是只有这个用户才有,其他用户并没有


原因

查看代码发现是通过ORM获取的,相当于SQL:

select id,credit_audit_id, admin_name,rejection, create_time from credit_audit_record where credit_audit_id = '56556' and alias = 'C1000100' and save_status = 0;


SQL并没有加order by来排序,那一般情况下,是使用主键来进行正序排序的,看一下表结构:

> desc credit_audit_record;
+--------------------+---------------------+------+-----+---------------------+----------------+
|       FIELD        |        TYPE         | NULL | KEY |       DEFAULT       |     EXTRA      |
+--------------------+---------------------+------+-----+---------------------+----------------+
| id                 | bigint(20) unsigned | NO   | PRI | NULL                | auto_increment |
| credit_audit_id    | int(10)             | NO   | MUL | NULL                |                |
| admin_id           | varchar(20)         | NO   |     |                     |                |
| admin_name         | varchar(30)         | NO   |     |                     |                |

可以看到,id是自增主键


我们直接使用sql来查看结果吧:

> select id,credit_audit_id, admin_name,rejection,create_time from credit_audit_record where credit_audit_id = '56556' and alias = 'C1000100' and save_status = 0;
+--------+-----------------+------------+-----------+---------------------+
|   ID   | CREDIT AUDIT ID | ADMIN NAME | REJECTION |     CREATE TIME     |
+--------+-----------------+------------+-----------+---------------------+
| 109962 |           56556 |            |           | 2022-01-02 17:00:01 |
| 112294 |           56556 | aaa     |           | 2022-01-10 14:42:17 |
| 112653 |           56556 | bbb     |           | 2022-01-12 10:46:04 |
| 109963 |           56556 | ccc       |           | 2022-01-02 17:03:02 |
+--------+-----------------+------------+-----------+---------------------+

结果出乎意料,没有加order by的情况下,select的时候,并不是根据id来进行正序排序的


我一直以为不加order by的情况下,select的时候默认是会按照id进行正序排序的,但现实情况有可能不是的


查阅相关文档:

https://segmentfault.com/a/1190000016251056

https://blog.csdn.net/qq_35383263/article/details/81433693

https://www.imooc.com/article/4925


原因可能是:

MySQL SELECT 默认排序是按照物理存储顺序显示。(不进行额外排序)也就是说SELECT * FROM 会产生“表扫描”。如果表没有增,删,改操作,记录会显示为插入的顺序。这就是初始为什么像是递增的原因。

那么,当我们进行增,删,改以后不难发现会乱序,这便是问题所在。增删改是惯用功能,因此必须注意这个细节。当我们不进行ORDER BY来规定排序时,MySQL将会以最快的形式(物理存储顺序)展示数据,导致乱序。


结论是:

如果在sql语句中不指定order by排序条件,那么得到的结果集的排序顺序是与查询列有关的。因为不同的查询列可能会用到不同的索引,从而导致顺序不同,具体原因就不深究了。


看网上大神的说法是:没有条件的情况下,数据库默认排序顺序是不好确定的,也不应该决定于什么因素,不同的数据库实现不同.只能用order by 来限定。


反正,不要迷信mysql默认会按照你以为的顺序排序,想要排序就先给你想要排序的字段创建索引(提高效率),然后再order by这个字段进行排序。


总之一句话:

没有条件的情况下,数据库默认排序顺序是不确定的


解决

解决方法很简单,如果是需要排序的话,一定要加一个order by

猜你喜欢

转载自blog.csdn.net/jiandanokok/article/details/122504344