当没有指定order by时,SELECT TOP如何工作?

时间:2013-03-06 10:52:08

标签: sql sql-server tsql select sql-order-by

msdn documentation说我们写的时候

SELECT TOP(N) ..... ORDER BY [COLUMN]

我们获得按column排序的前(n)行(ascdesc,具体取决于我们选择的内容)

但是如果我们没有指定任何顺序,msdn说randomGail Erickson指出here。他指出它应该是unspecified,而不是random。但正如 Thomas Lee指出的那样

  

当TOP与ORDER BY子句一起使用时,结果   set仅限于前N个有序行数;否则,它   返回前N个行ramdom

所以,我在一个没有任何索引的表上运行了这个查询,首先我运行了这个..

SELECT *
FROM
    sys.objects so
WHERE
    so.object_id NOT IN (SELECT si.object_id
                         FROM
                             sys.index_columns si)
    AND so.type_desc = N'USER_TABLE'

然后在其中一个表中,(实际上我在上面查询返回的所有表中尝试了下面的查询)和我总是得到相同的行。

SELECT TOP (2) *
FROM
    MstConfigSettings

这总是返回相同的2行,对于查询1返回的所有其他表也是如此。现在执行计划显示3个步骤..

enter image description here

正如您所看到的,没有索引查找,它只是一个纯表扫描,

enter image description here

Top显示实际的行数不是2,Table Scan也是如此。事实并非如此(我有很多行)。

但是当我运行

之类的东西时
SELECT TOP (2) *
FROM
    MstConfigSettings
ORDER BY
    DefaultItemId

执行计划显示

enter image description here

enter image description here

所以,当我不申请ORDER BY时,步骤是不同的(没有排序)。但问题是,如果没有TOP,这个Sort如何运作?为什么以及如何总是给出相同的结果?

1 个答案:

答案 0 :(得分:20)

无法保证您获得哪两行。它只是从表扫描中检索到的前两个。

执行计划中的TOP迭代器将在返回两个后停止请求行。

可能对于堆的扫描,这将是分配顺序中的前两行,但这不能保证。例如,SQL Server可能使用advanced scanning功能,这意味着您的扫描将读取最近从另一个并发扫描中读取的页面。