据我所知,从关系数据库理论来看,没有select
子句的order by
语句应该被认为没有特定的顺序。但实际上在SQL Server和Oracle中(我在这两个平台上进行了测试),如果我从一个没有order by
子句的表中多次查询,我总是以相同的顺序得到结果。这种行为是否可以依赖?任何人都可以帮忙解释一下吗?
答案 0 :(得分:38)
不,不能依赖这种行为。顺序由查询计划程序决定构建结果集的方式决定。像select * from foo_table
这样的简单查询很可能按照它们存储在磁盘上的顺序返回,这可能是主键顺序或它们的创建顺序,或者其他一些随机顺序。更复杂的查询(例如select * from foo where bar < 10
)可以基于索引读取或表顺序以不同列的顺序返回,用于表扫描。使用多字where
条件,group by
子句union
s,更精细的查询将按计划程序决定最有效生成的顺序排列。
由于这些查询之间的数据发生了变化,订单甚至可以在两个相同的查询之间进行更改。一个查询中的索引扫描可能满足“where”子句,但后来的插入可能会使该条件的选择性降低,并且计划程序可以决定使用表扫描执行后续查询。
为此提出更好的观点。 RDBMS系统的任务是尽可能高效地为您提供完全您要求的内容。这种效率可以采取多种形式,包括最小化IO(磁盘以及通过网络向您发送数据),最小化CPU并保持其工作集的大小(使用需要最少临时存储的方法)。 p>
没有ORDER BY
子句,您将没有要求完全获取特定订单,因此RDBMS将以某种顺序为您提供这些行(可能)与某些巧合相对应查询的一个方面,基于RDBMS期望以最快的速度生成数据的任何算法。
如果您关心效率,而不关心订单,请跳过ORDER BY
子句。如果您关心订单而不关心效率,请使用ORDER BY
子句。
由于您实际关心 BOTH 使用ORDER BY
,然后仔细调整您的查询和数据库以使其有效。
答案 1 :(得分:6)
不,您不能依赖每次都以相同的顺序返回结果。我发现在使用分页网格的网页上工作时。当我转到下一页,然后回到上一页时,上一页包含不同的记录!我完全神秘化了。
对于可预测的结果,您应该包含ORDER BY
。即使这样,如果指定的列中存在相同的值,您也可以获得不同的结果。您可能需要ORDER BY
个字段,而这些字段并不是您认为不需要的,只是为了获得可预测的结果。
答案 2 :(得分:4)
Tom Kyte有一个pet peeve about this topic。无论出于何种原因,人们都对此着迷,并不断尝试提出您可以依赖特定订单而不指定ORDER BY的情况。正如其他人所说,你做不到。这是关于AskTom网站主题的another amusing thread。
答案 3 :(得分:1)
这是为纠正旧答案而添加的新答案。我从Tom Kyte得到答案,我在这里发布:
如果您想要排序行,则必须使用订单。不,如果,或,或者是关于它。期。 http://tkyte.blogspot.ru/2005/08/order-in-court.html您需要通过IOT订购。行在叶块中排序,但叶块不按存储排序。快速全扫描=未排序的行。
https://twitter.com/oracleasktom/status/625318150590980097
https://twitter.com/oracleasktom/status/625316875338149888
( 注意! 关于这个问题的原始答案仅仅是为了历史而放在这里。这是错误的答案。正确的答案是放置以上)
正如Tom Kyte在前面提到的文章中写道的那样:
您应该将堆组织表视为一个无序的大型表 行的集合。这些行将以看似随机的方式出现 顺序,并取决于使用的其他选项(并行查询, 不同的优化器模式等等,它们可能会有所不同 订单使用相同的查询。不要依赖于行的顺序 查询,除非您的查询中有ORDER BY语句!
但请注意,他只讨论堆组织表。但也有索引表格。在这种情况下,您可以依赖于没有ORDER BY
的select的顺序,因为主键隐式定义了顺序。对Oracle而言确实如此。
对于默认创建的SQL Server聚簇索引(索引组织表)。 PostgreSQL存储信息也有可能通过索引进行对齐。可以找到更多信息here
<强>更新强> 我明白了,我的答案正在减少。所以我会试着解释一下我的观点。 在索引组织表概述部分中,有一个短语:
在索引组织表中,行存储在表的主键上定义的索引中...当相关的数据必须存储在一起或者数据必须物理存储在一个数据中时,索引组织的表很有用。特定的顺序。
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
如果您不同意我的意见,请给我一个关于文件的链接。我很高兴知道有一些东西需要我学习。