私が知っているように、リレーショナルデータベース理論から、句のないselect
ステートメントorder by
は特定の順序を持っていないと見なされるべきです。しかし、実際にはSQL ServerとOracle(これら2つのプラットフォームでテスト済み)では、order by
句のないテーブルから複数回クエリを実行すると、常に同じ順序で結果が得られます。この動作は信頼できますか?誰かが少し説明するのを手伝うことができますか?
4 に答える
いいえ、その動作は信頼できません。順序は、クエリ プランナーが結果セットの構築を決定した方法によって決まります。のような単純なクエリselect * from foo_table
は、ディスクに保存されている順序で返される可能性が高く、主キーの順序、作成された順序、またはその他のランダムな順序である可能性があります。select * from foo where bar < 10
代わりに、インデックスの読み取りに基づいて別の列の順序で、またはテーブル スキャンの場合はテーブルの順序で返されるなど、より複雑なクエリ。where
複数の条件、group by
句、 sを含むさらに複雑なクエリはunion
、プランナーが生成するのに最も効率的であると判断した順序になります。
クエリ間でデータが変更されたという理由だけで、2 つの同一のクエリ間で順序が変わることさえあります。「where」句は、1 つのクエリのインデックス スキャンで満たされる場合がありますが、後で挿入するとその条件の選択性が低下する可能性があり、プランナーはテーブル スキャンを使用して後続のクエリを実行することを決定できます。
より細かい点を付けるために。RDBMS システムには、ユーザーが求めたものを可能な限り効率的に正確に提供する義務があります。その効率性には、IO の最小化 (ディスクおよびネットワーク経由でデータを送信するための両方)、CPU の最小化、ワーキング セットのサイズを小さく保つ (最小限の一時ストレージを必要とする方法を使用する) など、さまざまな形があります。
ORDER BY
句がなければ、特定の順序を正確に要求していないため、 RDBMS は、RDBMS が生成することを期待するアルゴリズムに基づいて、クエリの偶然の側面に (おそらく) 対応する順序で行を提供します。データ最速。
順序ではなく効率を重視する場合は、ORDER BY
節をスキップしてください。効率ではなく順序が重要な場合は、ORDER BY
句を使用します。
実際には両方の使用に関心ORDER BY
があるため、クエリとデータベースが効率的になるように慎重に調整してください。
いいえ、毎回同じ順序で結果が返されるとは限りません。ページングされたグリッドを持つ Web ページで作業しているとき、私はそれを発見しました。次のページに移動してから前のページに戻ると、前のページには別のレコードが含まれていました。私は完全に戸惑いました。
予測可能な結果を得るには、ORDER BY
. それでも、指定された列に同じ値がある場合は、異なる結果が得られる可能性があります。ORDER BY
予測可能な結果を得るために、実際には必要とは思わなかったフィールドが必要になる場合があります。
Tom Kyte は、このトピックについて不満を持っています。何らかの理由で、人々はこれに魅了され、ORDER BY を指定せずに特定の順序に依存できるケースを考え出そうとし続けています。他の方がおっしゃる通り、無理です。これは、 AskTom Web サイトのトピックに関する別の面白いスレッドです。
正しい答え
これは、古い回答を修正するために追加された新しい回答です。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
間違った答え
(注意!質問に対する元の回答は、歴史のためにのみここに置かれました。それは間違った答えです。正しい答えは上に置かれます)
トム・カイトが以前の記事で書いたように:
ヒープ構成のテーブルは、順序付けされていない行の大きなコレクションと考える必要があります。これらの行は一見ランダムな順序で出力され、使用されている他のオプション (並列クエリ、異なるオプティマイザー モードなど) によっては、同じクエリでも異なる順序で出力される場合があります。クエリに ORDER BY ステートメントがない限り、クエリからの行の順序を当てにしないでください。
ただし、彼が話しているのはヒープ構成テーブルについてのみであることに注意してください。しかし、索引構成表もあります。ORDER BY
その場合、順序が主キーによって暗黙的に定義されているため、選択の順序に依存できます。それはオラクルにも当てはまります。
既定で作成される SQL Server クラスター化インデックス (インデックス構成テーブル) 用。PostgreSQL ストア情報がインデックスで整列する可能性もあります。詳細はこちら
更新: なるほど、私の回答に反対票が投じられています。そこで、私の論点を少し説明しようと思います。索引構成表の概要のセクションに、次のフレーズがあります。
索引構成表では、行は表の主キーで定義された索引に格納されます... 索引構成表は、関連するデータをまとめて格納する必要がある場合、またはデータを特定の順序で物理的に格納する必要がある場合に役立ちます。
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
私に同意しない場合は、ドキュメントのリンクを教えてください。私にとって学ぶべきことがあると知ってうれしいです。