59

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

4

4 回答 4

63

不,不能依赖这种行为。顺序由查询计划器决定构建结果集的方式确定。像这样的简单查询select * from foo_table可能会按照它们存储在磁盘上的顺序返回,这可能是主键顺序或它们被创建的顺序,或者其他一些随机顺序。更复杂的查询,例如select * from foo where bar < 10可能会根据索引读取或表顺序以不同列的顺序返回,以进行表扫描。where具有多个条件、group by子句s 的更复杂的查询union将按照规划器决定最有效生成的任何顺序进行。

仅仅因为这些查询之间的数据发生了变化,两个相同查询之间的顺序甚至可能发生变化。“where”子句可能会满足一个查询中的索引扫描,但后来的插入可能会使该条件的选择性降低,并且计划程序可以决定使用表扫描执行后续查询。


把它放在一个更好的点。RDBMS 系统的任务是尽可能高效地准确地为您提供所需的内容。这种效率可以采取多种形式,包括最小化 IO(到磁盘以及通过网络向您发送数据)、最小化 CPU 并保持其工作集的大小较小(使用需要最少临时存储的方法)。

如果没有ORDER BY子句,您将不会确切地询问特定的顺序,因此 RDBMS 将根据 RDBMS 期望生成的任何算法,以某种顺序(可能)与查询的某些巧合方面对应的顺序为您提供那些行数据最快。

如果您关心效率而不是顺序,请跳过该ORDER BY子句。如果您关心顺序而不关心效率,请使用该ORDER BY子句。

由于您实际上关心两者的使用ORDER BY,然后仔细调整您的查询和数据库,使其高效。

于 2012-04-08T16:55:26.873 回答
9

不,您不能依赖每次都以相同的顺序返回结果。我在处理带有分页网格的网页时发现了这一点。当我转到下一页,然后再回到上一页时,上一页包含不同的记录!我完全被迷惑了。

那么,为了获得可预测的结果,您应该包括一个ORDER BY. 即使那样,如果那里的指定列中有相同的值,您可以获得不同的结果。您可能需要ORDER BY填写您认为并不真正需要的字段,只是为了获得可预测的结果。

于 2012-04-08T16:56:18.063 回答
4

Tom Kyte对这个话题很恼火。无论出于何种原因,人们都对此着迷,并不断尝试提出可以依赖特定订单而不指定 ORDER BY 的案例。正如其他人所说,你不能。这是AskTom 网站上关于该主题的另一个有趣的主题。

于 2012-04-08T17:25:46.543 回答
1

正确答案

这是为纠正旧答案而添加的新答案。我从 Tom Kyte 那里得到了答案,我把它贴在这里:

如果要对行进行排序,则必须使用订单。不,如果,并且,或但是关于它。时期。http://tkyte.blogspot.ru/2005/08/order-in-court.html您需要通过该物联网订购。行在叶块中排序,但叶块未排序存储。快速全扫描=未排序的行。

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

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


错误的答案

注意!问题的原始答案放在下面只是为了历史。这是错误的答案。正确的答案放在上面)

正如汤姆凯特在之前提到的文章中所写:

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

但请注意,他只谈论堆组织表。但也有索引组织表。在这种情况下,您可以依赖选择的顺序,而不是ORDER BY因为主键隐式定义的顺序。对于甲骨文来说确实如此。

对于默认创建的 SQL Server 聚集索引(索引组织表)。PostgreSQL 存储信息也可以按索引对齐。更多信息可以在这里找到

更新: 我明白了,我的回答被否决了。所以我会试着稍微解释一下我的观点。在索引组织表概述部分中有一个短语:

在索引组织的表中,行存储在表的主键上定义的索引中......当相关的数据必须存储在一起或数据必须以特定的顺序物理存储时,索引组织的表很有用。

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

如果您不同意我的观点,请给我一个文档链接。我很高兴知道有一些东西要学。

于 2014-10-28T11:48:08.900 回答