SQL查询中对已排序表使用ORDER BY是否冗余及性能问题
结论:查询语句中的
ORDER BY不是冗余操作,必须显式保留 - 首先要明确SQL的基本规则:SQL标准从来不会保证不带
ORDER BY子句的查询会按照表的物理存储顺序返回结果。你对表做的预排序写入、甚至是基于聚簇索引/CLUSTER命令做的物理存储排序,都只是存储层面的特性,不是查询结果的排序承诺。 - 你现在要查指定对象的变更记录,几乎一定会加
WHERE条件做过滤,这种场景下数据库优化器很可能选择对应过滤字段的二级索引做数据检索,此时返回结果的顺序会跟随二级索引的排序规则,和你预排序的time_updated DESC NULLS LAST规则完全无关。就算是不带过滤条件的全表查询,只要执行过程中触发了并行扫描、哈希运算、多表关联(哪怕当前语句没写join,后续统计信息变化、数据库版本升级都可能改变执行计划),返回顺序都会被打乱。 - 很多人担心额外加
ORDER BY会带来排序性能损耗,这个问题很好解决:只要创建(过滤字段名, time_updated DESC NULLS LAST)的联合索引,这个ORDER BY逻辑可以直接通过索引顺序满足,数据库不会执行额外的实时排序操作,没有额外性能开销。 - 不要靠"现在测试跑出来顺序是对的"就省略
ORDER BY,生产环境里依赖隐式排序导致的分页错乱、最新/最旧记录取错的故障非常常见,靠隐式行为省代码的风险远大于收益。
正确的查询写法参考:
-- 以拉取id=123的对象的最新1条变更记录为例 SELECT * FROM change_record WHERE object_id = 123 ORDER BY time_updated DESC NULLS LAST LIMIT 1;
只有查询语句中显式声明的
ORDER BY规则,才是数据库承诺的、稳定的结果集排序规则,任何隐式顺序都不可靠。
内容的提问来源于stack exchange,提问作者Makan Azarshahy
相关产品推荐
相关产品推荐

