サブクエリでのORDER BYのデータベース実装


10

SQLステートメントをラップするアプリケーション(MapServer- http://mapserver.org/)を使用しているため、ORDER BYステートメントは内部クエリにあります。例えば

SELECT * FROM (
        SELECT ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl

アプリケーションには、さまざまなデータベースドライバーがあります。主にMS SQL ServerドライバーとSQL Server 2008を使用しています。サブクエリでORDER BYが見つかった場合、エラーがスローされます。

MSドキュメントから(これはSQL Server 2000の場合ですが、まだ適用されているようです):

ビュー、インライン関数、派生テーブル、またはサブクエリでORDER BY句を使用する場合、順序付けされた出力は保証されません。代わりに、ORDER BY句は、Top演算子によって生成される結果セットの構成が一貫していることを保証するためにのみ使用されます。ORDER BY句は、最も外側のSELECTステートメントで指定されている場合にのみ、順序付けされた結果セットを保証します。

ただし、Postgres(9)およびOracleで実行した場合、同じタイプのクエリが結果を返します-サブクエリで定義された順序で。Postgresでは、クエリプランは結果がソートされていることを示し、Postgresのリリースノートには、サブクエリの順序が使用されることを意味する項目が含まれています。

サブクエリORDER BYが上位クエリと一致する場合はソートを回避

http://en.wikipedia.org/wiki/Order_byの状態:

一部のデータベースシステムでは、副選択またはビュー定義でORDER BY句を指定できますが、そこに存在しても効果はありません。

ただし、クエリプランの私自身のチェックから:

  • SQL Server 2008はサブクエリでのORDER BYをサポートしていません
  • Postgres 9はサブクエリでのORDER BYをサポートしています
  • Oracle 10gはサブクエリでのORDER BYをサポートします

だから私の質問は、PostgresとOracleがサブクエリでの並べ替えを許可していないことを正式に確認または否定できるリンクはありますか?


2
特定の結果を観察したからといって、それらが保証されるわけではありません。整合性が必要な場合は、外側で注文してください。限目。
アーロンバートランド

理想的には、これが実装されます。ただし、この段階に到達するには、コアロジックと多くのデータベースドライバーへの変更が含まれます。この問題は何年も報告されていないため、一部のデータベースはサブクエリでORDER BYを一貫して実装しているようです。可能であれば、どれを知っておくとよいでしょう。
geographika

2
@geographika一部のDBMSが現在まで一貫して実行している場合でも、それらが将来も同じように動作し続ける保証はありません。例として、5.6(およびMariaDB 5.3)でのオプティマイザのMySQLの改善によりORDER BY、サブクエリ内のが冗長であると識別され、不必要なソートが行われなくなります。
ypercubeᵀᴹ

回答:


15

あなたは、あなたのアプリケーションを作るために必要があるとしているではない入れORDER BYサブクエリの内側(多分それは最初の場所で不要な副問合せを使用しないためのオプションを持っています)。すでに発見したように、この構文はSQL ServerではサポートされていませんTOP。またTOP、を使用すると、一部の行を省略しない限り、とにかく最適化されてTOP 100 PERCENTレンダリングORDER BYされます。

OracleとPostGresでは、構文がサポートされているからといって、それが遵守されているわけではありません。また、一部のシナリオで従うものとして観察したからといって、新しいバージョンが出たり、データ、統計、クエリ自体、または環境に微妙な変更が加えられても従うことを意味するものではありません。

私は、ことを保証することができます疑いもなくしたい場合は、保証の順序については、あなたが配置する必要がありORDER BY、最も外側のクエリに。これは、どのプラットフォームを使用している場合でも、しっかりと守るべき原則です。

あなたは何かがサポートされていないことを公式に述べるリンクを求めています。これは、自動車のオーナーズマニュアルで、自動車が飛行できないという公式声明を探すようなものです。


ありがとう。MSSQLはエラーをスローするのに適切なアプローチを持っていると思います。中核となるSQLの原則に反する場合、内部クエリでの並べ替えをサポートすることも実装することも、災いのレシピのようです。わからない程度の車のアナロジーけれども-あなたは手動でそれを探して追加する必要があり、車は実際に飛んでいる間に...
geographika

-1

これは不適切なことですが、問題が発生した場合は、サブクエリの最上位の行数を返してみてください。上位100%を返すことはできませんが、問題を解決したい場合は、行数をクエリしてTOPに変数として渡すことができます。互換性レベル80に設定されたデータベースでこれをテストしたので、SQL 2000で動作するはずです。

SELECT * FROM (
        SELECT TOP (100000) ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl

私はもともとこれを試しました、そしてそれは小さなデータセットのためにうまくソートするようでした。ただし、非常に大きなレコードセットを取得していたとき、SQL Server 2008R2では並べ替えが再びランダムになりました。多分メモリ/ページサイズに関連していますか?
geographika

役に立たなかったのは残念。上位100%を選択すると、並べ替えがランダムに戻ります。
DBNull 2014年

これは、クエリが並列になる場合、特にName一意でない場合は機能しません。オプティマイザがキー列の順序が異なる別のインデックスを選択した場合、連続して機能しない可能性があります。
エリックダーリン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.