web-dev-qa-db-ja.com

デフォルトのソート順を処理するためのSQLのベストプラクティス

私が読んだSQLコードの多くは、開発者はデフォルトのソート順が常に保持されると想定しているようです。たとえば、HTML選択リストを作成する場合、SELECT id, name FROM tableを発行せずにORDER BY句。

私自身の経験から、dbmsは常にFIFO no ORDER BY句が指定されており、インデックスがありません。ただし、順序は保証されません。しかし、テーブルに変更がない場合、dbmsがデータを並べ替えるのを見たことがありません。

テーブルに変更がない場合に、決定論的でない順序でデータを選択するdbmsを経験したことがありますか?

常にORDER BY句を配置するのがベストプラクティスですか?

35
Yada

デフォルトのソート順はありません。テーブルにクラスター化インデックスがある場合でも、その順序で結果が得られるとは限りません。特定の順序が必要な場合は、order by句を使用する必要があります。

50
HLGEM

他の投稿者が言及しているように、並べ替え順序を指定しない場合、SQL標準では、クエリプロセッサが最も適切で効率的な方法で結果を取得できるとしています。

インデックスも主キーもないCUSTOMERテーブルのすべての行に対して単純な順不同のSELECTを実行するとします。クエリプロセッサがストレートテーブルスキャンを実行し、最初に挿入された順序で行を生成することは十分にあり得ます(FIFOの動作を確認できます)。

次に、STATEフィールドとCITYフィールドに(この順序で)インデックスを追加し、WHERE STATE = 'NY'クエリプロセッサは、全テーブルスキャンを実行するよりも、STATE = 'NY'のインデックスエントリをスキャンする方が効率的であると判断する場合があります。この場合、おそらくSTATE、CITYの順序で行が具体化されます。

これでも確かではありません。たとえば、クエリプロセッサが統計情報を収集して、テーブル内のほとんどすべてのSTATE値が「NY」であることを示している場合(データベースがアルバニーベースの機器レンタルビジネス用であるためと思われます)、テーブルスキャンの方が実際に安いと判断する場合がありますインデックススキャンよりも、FIFOが再び表示されます。

データベースがクエリをどのように計画するかについて、いくつかの基本を学ぶことをお勧めします。 EXPLAINステートメントを使用して、DBMSが特定のクエリを実行する方法を確認し、これを使用してクエリを最適化することができます。これは、学ぶのに魅力的で役立つ分野です。

17
Jim Ferrans

データを一貫した順序で出力したい場合は、はい-ORDER BYを使用する必要があります。

9
OMG Ponies

はい。 ORDER BYがなければ「デフォルトの順序」はありません。また、データがFIFO/LIFOまたはその他の順序で返される保証はありません。

「SELECT id、name FROM table」を使用している開発者に関しては、それらは無能であるか、または何がどのような順序で出現するかを気にしません。

6
Ken White

重大なRDBMSはいかなる順序も保証しませんnless明示的なORDER BYを指定します。

それ以外のものは、純粋な運または変則的なものです-注文したい場合は、ORDER BYを指定する必要があります-それを回避する方法はありません。

3
marc_s

データの順序付けが必要な場合、何かを保証する唯一の方法(私が知っているすべての主要なRDBMSシステムで、間違いなくSQL ServerとOracle)は、ORDER BY句を含めることです。 FIFOは、ORDER BY句なしでデータが返される順序とはまったく関係がなく、どのような種類のDEFAULTソート順序の概念もありません。いわゆるDEFAULTソート順序は基本的にただし、エンジンはデータを取得します。これは、インデックス、キャッシュされたデータ、同時実行クエリ、サーバーへのロードなどに基づいて、文字通り任意の順序である可能性があります。

この他のstackoverflowスレッド は基本的にSql Serverに関連して同じ概念をカバーしています AlexKがリポジトリをブログに書いた 動作を示します。

3
boydc7

私のSQLの経験では、ほとんどの場合、SQLでORDER BYを指定しません。レコードセットは "client -side "動的な並べ替えがサポートされているグリッドタイプコントロールなど-この場合、SQLによる順序付けはneedlessとにかくクライアント側でチェックされるため。

同じクエリを使用して、データを異なる場所に異なる順序で表示する可能性があるため、これもクライアント側で行われます。

したがって、ORDER BYを配置するのは、次の場合にのみベストプラクティスです。

  • データの順序[〜#〜] is [〜#〜]重要;そして
  • ソートは、DBレベルでより効率的です。

つまり、フロントエンドの開発者がとにかく「再ソート」する場合、全体の処理時間を節約することはほとんどないため、意味がありません。

3
simo.3792

SELECT ... FROM tableのような単純なクエリでも、さまざまな順序でデータを返すことができます。これは理論的には真実であり、実際には真実であることがわかっています。また、テーブルでデータの変更が発生しなくても、後続の実行間で順序が変わる場合がたくさんあります。

実行間の順序変更の典型的な例は、クエリが並列プランを使用して実行される場合です。並列演算子は、基になるスレッドがデータを生成するとデータを返すため、結果の行の順序は実行ごとに異なります。この状況では、例の単純なSELECTでも、実行するたびにまったく異なる結果が返されます。

3
Remus Rusanu

おそらく、あなたが読んでいるこれらのSQLクエリの作成者は、返されるデータの順序を気にしません。ベストプラクティスは、返される結果の順序を確認する必要がある場合に使用することです。

1
Mike Atlas

私がしたようにこれを使用したい場合に備えて、これを書いています。

さて、私は満足のいくデフォルトのソート順を取得しています。たとえば、インデックスでのソートを使用して、ログテーブルの場合です。たとえば、通常はログテーブルの最後の行(LIFO)に関心があるので、DateTime DESCを順序として作成します。私はまた、主キーの横にある他のフィールド(整数)にIndexを追加することを楽しみにしてみましたが、うまくいきました。

CREATE TABLE [dbo].[tableA]([DateTime] [datetime] NOT NULL,
CONSTRAINT [PK_tableA] 
PRIMARY KEY CLUSTERED ([DateTime] DESC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]

またはSSMSで...

enter image description here

1
hoggar