2009-05-22 18 views
37

Oracleでは、「order by」句が指定されていない場合、選択クエリの行のデフォルトの順序は何ですか?oracleでの選択クエリのデフォルトの行順序付け

は、それが上記のすべての

  • なしでデフォルトの順序が存在しない行が挿入された順序
    1. です。
  • +0

    のORGANIZATION句でデータをINSERTしてテーブルに格納される順序を変更することができます。この質問は(私はそれはいくつかのフォーラムにポップアップ表示を見てきました)多くのことを尋ねます。私は、 "ORDER BY"がCBOに並べ替えを実行させるという誤った信念によって引き起こされると思います。これは、並べ替えられていないクエリを実行するより明らかに高価です。 Oracleのソート・パフォーマンスを向上させる方法はありますが、「ORDER BY」節を避ける必要はありません。 –

    答えて

    34

    Tom Kyteによると、「問合せに「順序付け」を追加するまでは、返される行の順序については何も言えません。まあ、「行の順序に頼ることはできません。戻ってきた'。"

    this question asktom.comを参照してください。

    ROWNUMは物理的に存在しないため、「解放」することはできません。 ROWNUMは、レコードがテーブルから取得された後に割り当てられます。このため、「WHERE ROWNUM = 5」は常にレコードを選択できません。

    @ammoQ:GROUP BY発注のthis AskTom articleをお読みになりたい場合があります。要するに:

    は BY句NO注文がなくても、出力データは が ために、GROUP BY列でソートされることをgauranteeグループは、クエリでWHERE句ではいますか?

    と我々は言った...

    絶対にありません、

    それはありません、それがなかったことはありません、それは決して 意志。

    +0

    ありがとう、私はその記事を知っています。 2年前、文字通り数週間かけて質問をした後、私はこのプログラムを10gでどういうふうに振る舞うのですか? –

    +0

    簡単に言えば、Oracleは10gで何か別のことをしているからです。しかし、Oracleのバグではありません! Oracleは結果をソートしません。Tomは9iでどのように失敗するかを示します。それはしばしば、人々がそれに頼っていることを意味するように見えたからです。その記事は、有益であることに加え、単純な概念を受け入れることができない、あるいは受け入れたくないという最も驚くべきイラストの1つです。なぜなら、それは彼ら自身の事例とは異なるからです。それはまたかなり面白いです。データをソートしたい場合は、注文を使用してください。 – DCookie

    +0

    @DCookieこの動作はOracleに限られているか、MySQL、Postgresなどのすべてのリレーショナルデータベースに適用できますか? –

    -5

    私はそれがOracleの隠されたRownum属性を使用すると信じています。

    あなたの#1は、後で使用するためにrownumsを解放したかもしれない削除が行われなかったと仮定して、おそらく正しいでしょう。

    編集:他の人も言っているように、あなたは本当にこれに頼るべきではありません。削除以外にも、デフォルトのソート動作に影響を与えるさまざまな条件があります。

    +1

    ROWNUMは属性ではありませんが、照会時にのみ割り当てられます。 ROWIDは属性でもなく、単にファイル、ブロック、行を単一の値として表現します。それは、実際の行へのポインタとしてインデックスに格納されます。 –

    19

    明示的なデフォルト順序はありません。明らかな理由から、新しいテーブルを作成し、いくつかの行を挿入し、 "where *"節なしで "select *"を実行すると、挿入された順に行が返されます。

    しかし、あなたは決してデフォルトオーダーに頼るべきではありません。特定の注文が必要な場合は、「注文」句を使用します。たとえば、Oracle 9iまでのバージョンでは、「グループ別」を実行すると、行がグループ式によってソートされていました。 10gでは、この動作はもはや存在しません! Oracleのインストールをアップグレードすると、これによりいくつかの作業が発生しました。

    +4

    答えにはいっていますが、ニック・ピック: 実際にはそうではありません。実際には、新しい行が特定の順序で新しい表に挿入される保証はなく、ORDER BYのないSELECTが必ずすべてを訪問するという保証はありませんそれらが作成されたのと同じ順序でテーブル内のブロック。 –

    +2

    はい、保証自体はありません。しかし、私はそれがうまくいかないシナリオを作るのは難しいでしょう。 –

    +3

    レコードを100にしてテーブルを作成し、最初の50を削除して別の10を挿入すると、Oracleは削除された行のスペースを再利用する傾向があります(多くのif、butなど)。したがって、たとえOracleが同じ順序でブロックを訪問しても、挿入された最後の10個のレコードは、ORDER BY –

    -3

    しかし、それはrownnum(あなたの#2)でなければなりませんが、実際には保証されておらず、100%信頼してはいけません。

    +1

    rownumは順序を報告します行*が返されます。彼らは返されるべき順序であなたを助けません。 –

    4

    ORDER BY句を指定しないと、Oracleは必要な順序で行を渡すことができます。 ORDER BY句を指定しないときの順序を指定するのは無意味です。それをあなたのコードに頼ることは、「キャリアを制限する動き」です。

    簡単な例:

    SQL> create table t as select level id from dual connect by level <= 10 
        2/
    
    Tabel is aangemaakt. 
    
    SQL> select id from t 
        2/
    
         ID 
    ---------- 
         1 
         2 
         3 
         4 
         5 
         6 
         7 
         8 
         9 
         10 
    
    10 rijen zijn geselecteerd. 
    
    SQL> delete t where id = 6 
        2/
    
    1 rij is verwijderd. 
    
    SQL> insert into t values (6) 
        2/
    
    1 rij is aangemaakt. 
    
    SQL> select id from t 
        2/
    
         ID 
    ---------- 
         1 
         2 
         3 
         4 
         5 
         7 
         8 
         9 
         10 
         6 
    
    10 rijen zijn geselecteerd. 
    

    そして、これが唯一の簡単な削除+挿入した後です。そして、考えられる他の多くの状況があります。並列実行、パーティション、索引構成表

    ボトムラインは、ammoQによって既によく知られています。ソートされた行が必要な場合は、ORDER BY句を使用します。

    +3

    +1されていないクエリからの注文に依存する "キャリア制限移動"の+1。 – Ollie

    +0

    アトリビューションについては、http://tkyte.blogspot.com/2005/08/order-in-court.html –

    +0

    リンクをありがとうございます。それは私が実際にその引用を得たところです。 –

    2

    order byを指定しない限り、注文に依存することは絶対にできません。特にOracleの場合、私は実際に(結合なしで)まったく同じクエリを見ており、その間に数秒間に2回実行され、その間に変化しなかったテーブルでは、大きく異なる順序を返します。これは、結果セットが大きい場合に発生する可能性が高いようです。

    Rob van Wijkの並列実行がこれを説明していると思います。オラクルのUsing Parallel Execution文書も参照してください。

    -2

    インデックスがある場合は、 インデックスの影響を受けますが、インデックスがない場合は 昇順を返します。挿入された注文を返します。

    -1

    あなたは、CREATE TABLE文の