none
Identity列を主キーとするテーブルからのSELECT結果のソート順について RRS feed

  • 質問

  • Identity列 「ID」(主キー)を保有する明細のテーブルから、アプリケーションにSELECT結果を

    取得しています。SELECT結果は常にIdentity列で昇順にソートされたデータが返ってくる
    ので、この順番を信頼し、特に

     ORDER BY ID ASC 

    などとアプリケーション側に書かずにアプリケーションを稼働していました。
    (なお、アプリケーション側からの書き込みの際は、明細のデータを上位テーブルのキーで
    一括DELETEし、INSERTするという上書き手法を取っていました。) 

    ところが、ある日、一部の明細データをメンテナンス的に介入して上書きする必要が
    出てきたため、UPDATE文を発行しました。(このテーブルにUPDATE発行が行われたのは
    これが初めて)

    すると、今までは、Identity列で昇順にソートされたデータが、ごくたまに、真逆の順序で
    返ってくるという現象が出だしました。

    そこで、アプリケーション側で、必ず昇順でデータが取得できるよう、

    ORDER BY ID ASC   を追記しました。

    対応としてはこれで万全でしょうか?
    「データが、ごくたまに、真逆の順序で返ってくるという現象」は発生頻度が
    低く、現象を解決したという手応えがはっきりと掴めないままでいます。

    宜しくお願いいたします。

    追記:UPDATEによる介入を行ったのと同じ時期に、検索スピードを上げるために、
    明細テーブル内の、親テーブルのキー値を保有する列にインデックスを作成しま
    した。影響しているのはこちらの方かも知れません。

    2012年8月23日 2:58

回答

  • > ORDER BY ID ASC   を追記しました。
    > 対応としてはこれで万全でしょうか?

    それで大丈夫ですがちょっと解釈が間違っています。
    ORDER を指定しない場合、どういう順番でレコードを取得するかは不定ですので、むしろ今までがたまたま上手くいっていたと考えるべきです。
    取得する順番を指定したいのならかならず ORDER BY で指定しましょう。

    > 追記:UPDATEによる介入を行ったのと同じ時期に、検索スピードを上げるために、
    > 明細テーブル内の、親テーブルのキー値を保有する列にインデックスを作成しま
    > した。影響しているのはこちらの方かも知れません。

    インデックスを貼ることで期待通りの順番になったとしても上記の通り、その順番は保証されません。
    • 回答としてマーク FELIKKS 2012年8月23日 3:43
    2012年8月23日 3:35

すべての返信

  • > ORDER BY ID ASC   を追記しました。
    > 対応としてはこれで万全でしょうか?

    それで大丈夫ですがちょっと解釈が間違っています。
    ORDER を指定しない場合、どういう順番でレコードを取得するかは不定ですので、むしろ今までがたまたま上手くいっていたと考えるべきです。
    取得する順番を指定したいのならかならず ORDER BY で指定しましょう。

    > 追記:UPDATEによる介入を行ったのと同じ時期に、検索スピードを上げるために、
    > 明細テーブル内の、親テーブルのキー値を保有する列にインデックスを作成しま
    > した。影響しているのはこちらの方かも知れません。

    インデックスを貼ることで期待通りの順番になったとしても上記の通り、その順番は保証されません。
    • 回答としてマーク FELIKKS 2012年8月23日 3:43
    2012年8月23日 3:35
  • >それで大丈夫ですがちょっと解釈が間違っています。
    >ORDER を指定しない場合、どういう順番でレコードを取得するかは不定ですので、むしろ今までがたまたま上手くいっていたと考えるべきです。
    >取得する順番を指定したいのならかならず ORDER BY で指定しましょう。

    なるほど、ありがとうございます。これからは必ず明示的に
    ORDER BY 指定を行う記述を心がけます。
    再現性の低い現象だったため、このようなフォーラムで何らかの確証が得られたら、と思っていました。
    回答が頂けて安心しました。

    ありがとうございました。

    2012年8月23日 3:45
  • すると、今までは、Identity列で昇順にソートされたデータが、ごくたまに、真逆の順序で
    返ってくるという現象が出だしました。

    テーブルにインデックスの中でもクラスター化インデックスが設定されていたのだと思います。この場合、ディスク上に格納する際にインデックス順に並べ替えてから格納されます。

    ですので、単純に呼び出すと偶然にもインデックス順に並んでいたということになります。クエリの条件式の都合などで順序が崩れたり逆順になるのは「SQL Serverとしてはクエリ時には特に順序を意識せずに読み込んだから」になります。

    回答そのものはgalacoさんが既に書かれている通りです。

    2012年8月23日 4:02
  • テーブルにインデックスの中でもクラスター化インデックスが設定されていたのだと思います。この場合、
    >ディスク上に格納する際にインデックス順に並べ替えてから格納されます。

    なるほど、ありがとうございます。

    2012年8月23日 4:37