10

直到最近我开始每天使用它时,我才很少使用 SQL。我注意到如果没有使用“order by”子句:

  1. 选择表格的一部分时,如果我选择整个表格,返回的行似乎与它们出现的顺序相同
  2. 从连接中选择返回的行的顺序似乎是由连接的最左边的成员决定的。

在最常见的数据库(MySql、Oracle、PostgreSQL、Sqlite、Sql Server)中,这种行为是一种可以指望的标准吗?(我什至不知道是否可以在 sqlite 中真正指望它)。如果是这样,它的尊重程度有多严格(例如,如果使用“分组依据”,各个组是否都有该排序)?

4

5 回答 5

14

如果查询中不包含 ORDER BY 子句,则返回的行顺序未定义。

尽管即使省略了 ORDER BY 子句,某些 RDBMS 在某些情况下也会以特定顺序返回行,但绝不应依赖这种行为。

于 2012-05-02T16:53:26.167 回答
13

SQL-92 规范的第 20.2 节 <直接选择语句:多行>,“一般规则”小节:

4) 如果 <order by 子句> 没有指定,那么
   Q 的行是依赖于实现的。
于 2012-05-02T16:53:32.320 回答
10

如果您想要订购,请包含一个ORDER BY. 如果你不包括ORDER BY,你告诉 SQL Server:

我不在乎您返回行的顺序,只需返回行

由于您不在乎,SQL Server 将决定如何返回它认为现在可能最有效的方式(或根据上次缓存此特定查询的计划的时间)。因此,您不应依赖您观察到的行为。它可以从一次查询运行更改为下一次查询,包括数据更改、统计信息更改、索引更改、服务包、累积更新、升级等等等。

于 2012-05-02T16:56:22.473 回答
4

对于 PostgreSQL,如果您省略该ORDER BY子句,您可以在数据库未被修改的情况下运行完全相同的查询 100 次,并在中间以与其他顺序不同的顺序运行一次。事实上,每次运行的顺序可能不同。

发生这种情况的一个原因是,如果选择的计划涉及对表堆的顺序扫描,并且已经对该表的堆进行了 seqscan,那么您的查询将在另一个扫描已经在的任何点开始扫描,以减少对磁盘访问的需求。

正如其他答案所指出的那样,如果您希望数据按特定顺序排列,请指定该顺序。PostgreSQL 将在选择计划时考虑请求的顺序,并且可以使用按该顺序提供数据的索引,如果这样比以其他方式获取行然后对它们进行排序更便宜的话。

GROUP BY不提供订单保证;PostgreSQL可能对数据进行排序以进行分组,或者它可能使用哈希表并按照哈希算法生成的数字的顺序返回行(即非常随机)。这可能会从一次运行到下一次发生变化。

于 2012-05-02T17:40:18.563 回答
-1

当我还是一名 DBA 时,我总是惊讶于 SQL 的这个特性经常被认为是古怪的。考虑一个针对文本文件运行并产生一些输出的简单程序。如果程序永远不会改变,数据永远不会改变,那么您会期望输出永远不会改变。

至于这个:

如果查询中不包含 ORDER BY 子句,则返回的行顺序未定义。

不完全正确 - 在我曾经使用过的每个 RDBMS(Oracle、Informix、SQL Server、DB2 等等)上,DISTINCT 子句也与 ORDER BY 具有相同的效果,因为查找唯一值涉及按定义进行排序。

编辑(2014 年 6 月 2 日):

创建一个简单的表

在此处输入图像描述

对于 DISTINCT 和 ORDER BY,计划和成本都是相同的,因为它表面上是要执行的相同操作

在此处输入图像描述

在此处输入图像描述

毫不奇怪,效果是一样的

在此处输入图像描述

于 2012-05-02T21:10:34.607 回答