在没有ORDER BY子句的情况下按什么顺序获取行?


11

一位程序员正在测试和比较使用相同数据库结构和相同数据的同一应用程序,仅在两个单独的数据库中进行比较,一个数据库使用Oracle 8,一个数据库使用Oracle 9。

该应用程序运行不带 ORDER BY子句的查询。

他声称,ORDER-BY-less查询应在两个数据库中以相同顺序返回行。

我告诉他,除非您明确提供ORDER BY子句,否则不能保证同一行顺序

该数据库具有相同的索引和键。但是解释计划表明,在其中一个数据库中,引擎使用的是连接表之一的键,而在另一个数据库中,引擎使用的是另一个表的键。

他暗示这两个数据库环境不相等,这是因为它们具有不同的统计信息,不同的rdbms引擎等,但不是因为我未能复制原始数据库具有的每个索引。

我告诉他,ORDER BY如果命令真的那么重要,他必须明确提供一个条款。

问题

所以我可以更好地向他解释:

当您不显式提供ORDER BY子句时,查询以什么顺序获取行,为什么该查询不按相同顺序返回行?


3
它是未定义的。我不认为SQL规范规定了要返回记录的特定顺序,因此它将取决于实现。
罗伯特·哈维

1
@RobertHarvey这就是我告诉他的原因。实际上:根据定义,关系表必须没有特定的顺序。
图兰斯·科尔多瓦

1
即使在完全相同版本的软件上使用不同的索引也可能有意义,因为基于它为该数据库中的准确数据收集的索引统计信息,它可能更具选择性。因此,如果不指定顺序,您实际上就不能依赖顺序。
psr

实际上,您可以期望未索引列的第一个查询遵循“插入时间”的顺序;通过索引“更新时间”。连续的请求可能会被缓存的结果“污染”,因此非常随机。但是,永远不要依赖它-它可能会因版本,版本,参数,更新操作以及满月的恶劣天气而异。“未定义”是正确的答案,其他任何东西充其量只能是有根据的猜测。
SF。

1
RDMBS-es返回的结果集就是:sets,按照定义,它们没有特定的顺序。因此,RDBMS可以按喜欢的任何顺序返回它们,并在下一次查询执行时再次更改顺序。依靠没有ORDER BY子句的特定顺序将是一个错误。我总是试图向我的同事解释这一点,但是我只有一半时间:D。
Radu Murzea

Answers:


25

维基百科

ORDER BY子句标识使用哪些列对结果数据进行排序,以及应按哪个方向对它们进行排序(选项是升序还是降序)。如果没有ORDER BY子句,则SQL查询返回的行顺序是不确定的。

因此它是未定义的。

SQL规范没有说明要返回记录的特定顺序,因此它将取决于实现。

在表上没有索引的情况下,明智的顺序将是插入记录的顺序。在定义了主键的情况下,明智的顺序将是主键的顺序。但是,由于ANSI规范不需要特定的订单,因此要由供应商来决定,它们的敏感性可能与您或我的不同。

由于订单是不是在规范中陈述,是不明智的依靠特定供应商的实施的行为,因为它可以从一个供应商到另一个,并且供应商可能更改顺序,他们希望的任何时候,没有警告。

如您所说,ORDER BY如果顺序很重要,则只需包含该子句。


该查询具有多个联接表。因此,一个数据库引擎按一个条件对结果集进行排序,而另一个数据库引擎则使用另一个条件。显然,当提供ORDER BY子句时,两个查询均以指定顺序返回行。
图兰斯·科尔多瓦

+1 AFAICR甚至在您每次在特定数据库实例上执行任何给定查询时都可以更改顺序。
MarkJ 2013年

2
我要说的是,没有ORDER BY子句,唯一明智的结果顺序就是开销最少的东西。对于简单的数据库存储引擎和查询,通常是插入顺序(生成的主键与主键顺序相同)。但是一旦您有了哈希连接,我就希望顺序基本上是随机的。
Michael Borgwardt

2

显然指出该规范没有说明数据输入的顺序,这没有用。可能是因为他知道数据在磁盘上或内存中的某个位置,因此将其作为命令。问他从几个表中计算得到的数据的顺序是什么。即创建一个示例,在其中连接4个表,对其中2个表进行计算,然后仅返回计算出的值。

引擎以找到数据的顺序返回数据(不存在排序依据),但是如何找到数据取决于可以更改的因素-索引,统计信息,缓存。通常,数据将保持一致的顺序-但是如果您依赖顺序,则需要提出要求。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.