没有Order By子句的SQL Select语句的顺序

据我所知,从关系数据库理论来看,没有order by条款的select语句应该被认为没有特定的顺序。 但实际上,在SQL Server和Oracle(我在这两个平台上testing过)中,如果我从一个没有order by子句的表中多次查询,我总是以相同的顺序得到结果。 这种行为可以依靠吗? 任何人都可以帮忙解释一下?

不,这种行为是不可靠的。 顺序是由查询规划者决定构build结果集的方式决定的。 像select * from foo_table这样的简单查询很可能会按照它们存储在磁盘上的顺序返回,这可能是主键顺序或创build顺序,或者其他随机顺序。 更复杂的查询,比如select * from foo where bar < 10可能会按照不同列的顺序,基于索引读取或按表格顺序为表扫描返回。 甚至更复杂的查询, where条件, group by条款, union ,按照规划者决定的最有效生成的顺序进行。

这个顺序甚至可以在两个相同的查询之间改变,只是因为这些查询之间的数据已经改变了。 一个查询中的索引扫描可能会满足“where”子句,但后面的插入可能会使该条件的select性降低,并且规划人员可能决定使用表扫描来执行后续查询。


把它放在更好的点上。 RDBMS系统的任务是尽可能高效地为您提供所要求的内容。 这种效率可以采取多种forms,包括尽量减lessIO(将磁盘以及通过networking发送给您的数据),最大限度地减lessCPU并保持其工作集的大小(使用需要最less临时存储的方法)。

如果没有ORDER BY子句,那么您将不会精确地询问特定的顺序,因此RDBMS将按照某种顺序为您提供这些行(可能)与查询的一些巧合方面相对应,这些顺序基于RDBMS期望的任何algorithm产生最快的数据。

如果您关心的是效率,而不是订单,请跳过ORDER BY子句。 如果您关心订单而不是效率,请使用ORDER BY子句。

既然你真的关心使用ORDER BY ,然后仔细调整你的查询和数据库,以便它是有效的。

不,你不能依靠每次都以相同的顺序返回结果。 我发现,当使用分页网格的网页上工作。 当我进入下一页,然后回到上一页时,上一页包含不同的logging! 我完全迷惑了。

对于可预测的结果,那么你应该包括一个ORDER BY 即使如此,如果在那里的指定列中有相同的值,您可以得到不同的结果。 您可能需要ORDER BY字段,你不真的认为你需要,只是为了得到一个可预测的结果。

汤姆·凯特(Tom Kyte) 对这个话题有一个宠爱的看法 。 无论出于何种原因,人们都为此着迷,并不断尝试提出可以依赖特定订单而不指定ORDER BY的情况。 正如其他人所说,你不能。 这是AskTom网站上另一个有趣的话题。

正确答案

这是一个新的答案,以纠正旧的。 我从Tom Kyte那里得到了答案,我在这里发表:

如果你想sorting行,你必须使用一个命令。 没有,如果,或者只是关于它。 期。 http://tkyte.blogspot.ru/2005/08/order-in-court.html您需要在该物联网上订购。; 行在叶块中sorting,但叶块不存储sorting。 快速全扫描=未sorting的行。

https://twitter.com/oracleasktom/status/625318150590980097

https://twitter.com/oracleasktom/status/625316875338149888


错误的答案

注意!关于这个问题的原始答案只是为了历史而放在这里,这是错误的答案,正确的答案放在上面)

汤姆·凯特(Tom Kyte)在之前提到的文章中写道:

您应该将堆组织表视为大型无序的行集合。 这些行将以看似随机的顺序出现,并且根据正在使用的其他选项(并行查询,不同的优化器模式等),它们可能以相同的查询以不同的顺序出现。 除非查询上有ORDER BY语句,否则不要指望查询中的行的顺序!

但是请注意,他只是谈论堆组织表。 但是也有索引 – 委托表格。 在这种情况下,您可以依赖于没有ORDER BY的select的顺序,因为由主键隐式定义的顺序。 对于Oracle来说是这样的。

对于默认情况下创build的SQL Server聚簇索引(索引组织的表)。 PostgreSQL存储信息也有可能通过索引alignment。 更多信息可以在这里find

更新:我看到,我的答案是投票下来。 所以我会试着解释一下我的观点。 在“ 索引组织表概述 ”一节有一句话:

在索引组织的表中,行存储在表的主键上定义的索引中…索引组织的表格在相关的数据片必须存储在一起或数据必须按特定顺序物理存储时非常有用。

http://docs.oracle.com/cd/E25054_01/server.1111/e25789/indexiot.htm#CBBJEBIH

由于索引,所有的数据都按特定的顺序存储,我相信Pg也是如此。 http://www.postgresql.org/docs/9.2/static/sql-cluster.html

如果您不同意我的意见,请给我一个链接文件。 我会很高兴知道有什么东西要为我学习。