7

私は数年前からいくつかのデータベースエンジンでSQLを使用してきましたが、理論的な知識がほとんどないため、私の質問は一部の人にとっては非常に「初心者」になる可能性があります. しかし、それは今私にとって重要になったので、尋ねなければなりません。

一意でない列を持つテーブル URL を想像してくださいstatus。そして、質問のために、大量の行があり、ステータスがすべてのレコードで同じ値を持っていると仮定します。

そして、クエリを何度も実行するとします。

SELECT * FROM Urls ORDER BY status
  1. 毎回同じ行順序を取得しますか? 新しい行を追加するとどうなるでしょうか? 順序を変更しますか、それとも新しいレコードが結果の最後に追加されますか? 同じ注文が得られない場合、この注文はどのような条件に依存するのでしょうか?

  2. 上記のクエリと同じ順序を返しますかROW_NUMBER() OVER (ORDER BY status)、それとも異なる順序付けメカニズムに基づいていますか?

4

4 に答える 4

10

とても簡単です。信頼できる順序付けが必要な場合はORDER BY、すべての列の組み合わせが各行で一意になるように、句に十分な数の列を含める必要があります。それ以外は保証されません。

単一のテーブルの場合、通常、ソートするのに「興味深い」列をリストし、その後に主キー列を含めることで、必要なものを取得できます。PK はそれ自体で一意性を保証するため、組み合わせ全体も順序付けを一意に定義することが保証されUrlsます{Site, Page, Ordinal}

SELECT * FROM Urls ORDER BY status, Site, Page, Ordinal
于 2013-09-04T12:07:19.563 に答える
8

ORDER BYSQL Serverでは安定していません(私が知る限り、他のデータベースでも)。安定した並べ替えは、テーブル内で見つかったのと同じ順序でレコードを返すものです。

大まかな理由は非常に単純です。テーブルはセットです。彼らには秩序がありません。したがって、「安定した」ソートは意味がありません。

低レベルの理由は、おそらくより重要です。データベースは、並列ソート アルゴリズムを実装している可能性があります。このようなアルゴリズムは、デフォルトでは安定していません。

安定した並べ替えが必要な場合は、並べ替えにキー列を含めます。

これはドキュメントでほのめかされています:

OFFSET と FETCH を使用したクエリ リクエスト間で安定した結果を得るには、次の条件を満たす必要があります。

クエリで使用される基になるデータを変更してはなりません。つまり、クエリによって処理された行が更新されないか、クエリからのページに対するすべての要求が、スナップショットまたはシリアル化可能なトランザクション分離を使用して単一のトランザクションで実行されます。これらのトランザクション分離レベルの詳細については、「SET TRANSACTION ISOLATION LEVEL (Transact-SQL)」を参照してください。

ORDER BY 句に、一意であることが保証されている列または列の組み合わせが含まれています。

于 2013-09-04T12:07:21.983 に答える
0

「この出力はどのような順序で出力されますか」というSQLの質問に対する一般的な答えは、特に順序を要求しない限り、「サーバーがどのように感じても、クエリごとに同じではない可能性があります」です。

「myTable から上位 1000 個の myColumn を選択する」などの単純なものでさえ、任意の行を任意の順序で返すことができます。たとえば、サーバーは並列スレッドを使用でき、結果を返し始める最初のスレッドがテーブルの途中で読み取りを開始したか、myColumn を含むインデックスが使用されたため、アルファベット順で最初の productName (今回; 前回はインデックスの統計が異なるため、別のインデックスを選択し、最も古い 1000 のトランザクションを提供しました)...

理論的には、サーバーが「クエリに一致するこれらの 10 ページがメモリ キャッシュにありました。ディスクが残りを返すのを待つ間、これらのページを渡します...

于 2016-12-20T07:20:41.907 に答える