web-dev-qa-db-ja.com

Order By句のないSQL Selectステートメントの順序

私が知っているように、リレーショナルデータベース理論から、order by句のないselectステートメントは特定の順序ではないと見なされるべきです。しかし、実際にはSQL ServerとOracle(これら2つのプラットフォームでテストしました)では、order by句を使用せずにテーブルから複数回クエリを実行すると、常に同じ順序で結果が得られます。この動作は信頼できますか?誰でも少し説明するのを助けることができますか?

40
Just a learner

いいえ、その動作は当てにできません。順序は、クエリプランナーが結果セットを構築することを決定した方法によって決定されます。 select * from foo_tableのような単純なクエリは、主キーの順序、作成された順序、またはその他のランダムな順序でディスクに格納された順序で返される可能性があります。代わりに、select * from foo where bar < 10などのより複雑なクエリが、テーブルスキャンのインデックス読み取りに基づいて、またはテーブルの順序で、異なる列の順序で返される場合があります。複数のwhere条件、group by句、unionsを使用したさらに複雑なクエリは、プランナーが生成するのに最も効率的であると判断した順序になります。

クエリ間でデータが変更されたという理由だけで、2つの同一クエリ間で順序が変わることさえあります。 "where"句は1つのクエリでのインデックススキャンで満たされる場合がありますが、後で挿入するとその条件の選択性が低下し、プランナーはテーブルスキャンを使用して後続のクエリを実行することを決定できます。


細かい点を付けます。 RDBMSシステムには、できる限り効率的に、正確に求めたものを提供するという使命があります。その効率は、最小化IO(ディスクおよびネットワーク経由でデータを送信する)を最小化する)、CPUを最小化する、作業セットのサイズを小さくする(メソッドを使用する)最小限の一時ストレージが必要です)。

ORDER BY句がなければ、特定の順序についてexactlyを要求していないため、RDBMSは、(おそらく)偶然のいくつかの側面に対応する順序でそれらの行を提供しますRDBMSがデータを最も速く生成すると予想するアルゴリズムに基づいたクエリ。

順序ではなく効率を重視する場合は、ORDER BY句をスキップしてください。順序ではなく効率を重視する場合は、ORDER BY句を使用します。

実際には[〜#〜] both [〜#〜]を使用するので、ORDER BYを使用し、クエリとデータベースを慎重に調整して効率的にします。

いいえ、毎回同じ順序で結果を取得することに依存することはできません。ページグリッドのあるWebページで作業しているときに発見しました。次のページに移動してから前のページに戻ると、前のページには異なるレコードが含まれていました!私は完全に神秘的でした。

予測可能な結果を​​得るには、ORDER BYそれでも、指定された列に同じ値がある場合、異なる結果を得ることができます。 ORDER BY予測可能な結果を​​得るために、本当に必要だとは思わなかったフィールド。

7
DOK

Tom Kyteには このトピックについての意地悪 があります。なんらかの理由で、人々はこれに魅了されており、ORDER BYを指定せずに特定の順序に依存できる場合を考え続けています。他の人が述べたように、あなたはできません。 AskTom Webサイトのトピックにある 別の面白いスレッド です。

4
DCookie

正しい答え

これは、古い回答を修正するために追加された新しい回答です。 Tom Kyteから回答がありました。ここに投稿します。

行を並べ替える場合は、注文を使用する必要があります。いいえ、および、またはそれについてはありません。限目。 http://tkyte.blogspot.ru/2005/08/order-in-court.html そのIOTで注文する必要があります。行はリーフブロックでソートされますが、リーフブロックはソートされて保存されません。高速フルスキャン=未ソート行。

https://Twitter.com/oracleasktom/status/625318150590980097

https://Twitter.com/oracleasktom/status/625316875338149888


間違った答え

注意!質問の元の答えは、歴史のためだけにここに置いた。間違っている答え。正しい答えは上に配置されます)

Tom Kyteが前に述べた記事で書いたように:

ヒープ構成表は、行の大きな順序付けられていないコレクションと考える必要があります。これらの行は一見ランダムな順序で出力され、使用されている他のオプション(並列クエリ、異なるオプティマイザーモードなど)に応じて、同じクエリで異なる順序で出力される場合があります。クエリにORDER BYステートメントがない限り、クエリからの行の順序に頼らないでください。

ただし、彼はヒープ構成表についてのみ話していることに注意してください。しかし、インデックスで整理されたテーブルもあります。その場合、ORDER BYなしでselectの順序に依存できます。順序は主キーによって暗黙的に定義されているためです。 Oracleにも当てはまります。

SQL Serverクラスターインデックス(インデックス構成テーブル)の場合、デフォルトで作成されます。 PostgreSQLストアの情報がインデックスで整列する可能性もあります。詳細については、こちらをご覧ください こちら

UPDATE:なるほど、答えに投票があります。だから、私は私のポイントを少し説明しようとするでしょう。セクション Index-Organized Tables の概要には次のフレーズがあります。

索引構成表では、行は表の主キーに定義された索引に格納されます。索引構成表は、関連するデータを一緒に格納する必要がある場合、またはデータを特定の順序で物理的に格納する必要がある場合に役立ちます。

http://docs.Oracle.com/cd/E25054_01/server.1111/e25789/indexiot.htm#CBBJEBIH

インデックスのため、すべてのデータは特定の順序で格納されます。Pgについても同じことが言えると思います。 http://www.postgresql.org/docs/9.2/static/sql-cluster.html

あなたが私に同意しないならば、私にドキュメンテーションに関するリンクをください。私が学ぶべきことがあることを知ってうれしいです。

1