为什么SQL语句的结尾要加上ORDER BY NULL?
有时候我们会看到项目中有些SQL语句带有 ORDER BY NULL ,这时我们看的有点疑惑了。难道 ORDER BY NULL 是按null进行排序的意思么?关键是表中字段都是设置NOT NULL,那还怎么按照null排序?
我们在学习索引优化时知道, ORDER BY 后面字段建立索引,可利用索引有序性而不用对字段进行额外排序操作,以提升语句执行效率 。而null不是索引字段,也没代表什么实际的含义,那么在SQL语句带有 ORDER BY NULL 究竟有什么用?下面一起来一探究竟。
查看MySQL官方文档可以看到,官方对使用 ORDER BY NULL 给出的解析。大致意思是,在SQL语句中会隐含对 GROUP BY 列进行排序,如果在 GROUP BY 列后面加上 ORDER BY NULL 会去掉这个隐含排序,以提升语句查询的速度。
参看文档: https://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html
纸上得来终觉浅,绝知此事要躬行。下面我们利用EXPLAIN,来复现一下这个场景:
GROUP BY
GROUP BY + ORDER BY NULL
我们可以看到加上 ORDER BY NULL 之后可以看到Extra里面少了 Using filesort 。
Using filesort 表示对查询结果进行排序的意思。如果我们查询的结果集是非常大的,排序操作也将消耗较多的性能,如果去掉Using filesort,减少排序的步骤,将会对查询的效率有极大的提升。小小的改进,收益却是巨大的。
同时,在 stackoverflow 中发现有人说MySQL 8.0之后版本使用 ORDER BY NULL 将没有任何的查询性能上收益了。
原因是8.0版本之后, GROUP BY 的隐含排序已经去掉了,在 GROUP BY 后面使用 ORDER BY NULL 也不会出现5.7版本之前压制字段隐含排序的现象,所以也没有必要在SQL语句中加上 ORDER BY NULL 。在MySQL官方文档中也有相同的叙述,由于本人使用的是MySQL版本是5.7,感兴趣的小伙伴可以在8.0上复现一下这个场景。
参看文档: https://dev.mysql.com/doc/refman/8.0/en/order-by-optimization.html
如果使用8.0之前版本,在没有明确声明 ORDER BY 列时,可以在 GROUP BY 后加上 ORDER BY NULL 来提升查询的效率。
如果使用8.0之后版本, GROUP BY 后无需加 ORDER BY NULL ,但需留意结果集是未排序的。 GROUP BY 后无需加 ORDER BY NULL ,但需留意结果集是未排序的。