20

msdnのドキュメントには、次のように書かれています。

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

columnascまたはdesc選択した内容に応じて)ソートされた上位(n)行を取得します

ただし、順序を指定しない場合、msdn はここでrandom指摘Gail Ericksonしたように言います。彼が指摘するように、それはむしろそうであるべきです。しかし、そこで指摘されているようにunspecifiedrandom Thomas Lee

TOP を ORDER BY 句と組み合わせて使用​​すると、結果セットは順序付けされた最初の 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'

そして、それらのテーブルの1つで(実際、上記のクエリによって返されたすべてのテーブルで以下のクエリを試しました)、常に同じ行を取得しました。

SELECT TOP (2) *
FROM
    MstConfigSettings

これは常に同じ 2 行を返し、クエリ 1 によって返される他のすべてのテーブルにも同じことが当てはまります。実行計画は 3 つのステップを示しています。

ここに画像の説明を入力

ご覧のとおり、インデックス ルックアップはなく、純粋なテーブル スキャンであり、

ここに画像の説明を入力

Top、実際の行数が 2 であることを示していTable Scanます。そうではありません(多くの行があります)。

しかし、次のようなものを実行すると

SELECT TOP (2) *
FROM
    MstConfigSettings
ORDER BY
    DefaultItemId

実行計画が表示されます

ここに画像の説明を入力

ここに画像の説明を入力

そのため、適用しない場合ORDER BYは手順が異なります (並べ替えはありません)。しかし、問題は、何TOPもないときにこれがどのように機能Sortし、なぜ、どのようにして常に同じ結果が得られるのかということです.

4

1 に答える 1

22

どの 2 つの行が得られるかは保証されません。これは、テーブル スキャンから取得された最初の 2 つのみです。

実行計画のTOP反復子は、行が 2 つ返されると、行の要求を停止します。

ヒープのスキャンの場合、これは割り当て順序の最初の 2 行になる可能性がありますが、これは保証されません。たとえば、SQL Server は高度なスキャン機能を使用する場合があります。これは、スキャンが別の同時スキャンから最近読み取られたページを読み取ることを意味します。

于 2013-03-06T10:55:17.080 に答える