SQL Select语句中没有Order By子句的顺序
在SQL中,如果在SELECT语句中没有明确指定ORDER BY子句,查询结果的顺序是不确定的。这个问题的出现源于人们对于这个话题的着迷,他们一直试图找出在不指定ORDER BY的情况下可以依赖特定顺序的案例。然而,正如其他人所指出的,实际上是不可能的。
Tom Kyte对于这个话题非常痛恨。他在Oracle的问答网站上写了一篇关于这个话题的博文,他在博文中解释了为什么不能在没有指定ORDER BY的情况下依赖特定顺序。
在这个博文中,Tom Kyte提到了一个有趣的帖子,这个帖子也是关于这个话题的。你可以在AskTom网站上找到这个帖子。
,如果在SQL的SELECT语句中没有明确指定ORDER BY子句,查询结果的顺序是不确定的。为了确保查询结果按照特定顺序返回,必须使用ORDER BY子句来指定排序规则。
在SQL查询语句中,如果没有使用ORDER BY
子句,就不能保证每次执行查询时返回的结果顺序相同。这可能导致在分页显示数据时出现问题,比如在网页上使用一个分页表格。当我从一个页面跳转到下一个页面,然后返回到上一个页面时,发现上一个页面包含的记录不同了,这让我感到非常困惑。
为了获得可预测的结果,应该在查询语句中包含ORDER BY
子句。即使使用了ORDER BY
,如果指定的列中存在相同的值,仍然可能得到不同的结果。为了获得可预测的结果,有时候还需要对不是必需的字段进行ORDER BY
。
所以,为了确保在执行SQL查询时得到一致的结果顺序,应该始终使用ORDER BY
子句,并且根据实际需要对多个字段进行排序。这样可以避免在分页显示数据等情况下出现不一致的结果。
在SQL查询中,如果没有明确指定ORDER BY
子句,查询结果的顺序是不可靠的。查询结果的顺序由查询规划器决定。简单的查询,如select * from foo_table
,可能按照存储在磁盘上的顺序返回,这可能是按照主键顺序、创建顺序或其他随机顺序。更复杂的查询,如select * from foo where bar < 10
,可能根据索引读取或表顺序返回不同列的顺序。更加复杂的查询,带有多个where
条件、group by
子句、union
操作,将按照查询规划器认为最高效的顺序生成结果。
甚至两个相同的查询之间的顺序可能会发生变化,这是因为这两个查询之间的数据发生了变化。一个"where"条件可能在一个查询中满足索引扫描,但是之后的插入操作可能使得该条件的选择性降低,查询规划器可能决定使用表扫描执行后续查询。
更准确地说,关系数据库管理系统(RDBMS)的任务是以尽可能高效的方式给出你所要求的结果。这种效率可以采取多种形式,包括最小化I/O(包括磁盘和网络上发送数据到客户端的开销)、最小化CPU使用以及保持其工作集的大小(使用需要最小临时存储空间的方法)。
如果你只关心效率而不关心顺序,可以省略ORDER BY
子句。如果你只关心顺序而不关心效率,可以使用ORDER BY
子句。既关心顺序又关心效率,那么就要使用ORDER BY
并仔细调优查询和数据库,使其高效。
另一个始终包含ORDER BY
的原因是SQL Server Enterprise Advanced Scan,也称为Merry-Go-Round Scan(在Dmitri Korotkevitch的优秀著作《Pro SQL Server Internals》中提到)。