ORDER BY NULL什么梗?
有时候我们会看到项目中有些SQL语句带有ORDER BY NULL
,这时我们看的有点疑惑了。难道ORDER BY NULL
是按null进行排序的意思么?关键是表中字段都是设置NOT NULL,那还怎么按照null排序?
我们在学习索引优化时知道,ORDER BY 后面字段建立索引,可利用索引有序性而不用对字段进行额外排序操作,以提升语句执行效率。而null不是索引字段,也没代表什么实际的含义,那么在SQL语句带有ORDER BY NULL
究竟有什么用?下面一起来一探究竟。
MySQL 5.7
查看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,减少排序的步骤,将会对查询的效率有极大的提升。小小的改进,收益却是巨大的。
MySQL 8.0
同时,在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
注意:在没有明确声明
ORDER BY
列时,MySQL 8.0和之前的版本的GROUP BY
后的结果集是不一致的。这也很好理解:8.0版本取消隐含排序,之前版本是带有隐含排序的,所以两者的结果集也就不一致了。
小结
如果使用8.0之前版本,在没有明确声明ORDER BY
列时,可以在GROUP BY
后加上ORDER BY NULL
来提升查询的效率。
如果使用8.0之后版本,GROUP BY
后无需加ORDER BY NULL
,但需留意结果集是未排序的。GROUP BY
后无需加ORDER BY NULL
,但需留意结果集是未排序的。