ORDER BYがビューに属さないのはなぜですか?


51

はあなた視野に入れないこと理解し ています 。(少なくとも私が作業しているSQL Server 2012では) ORDER BY

また、ビューを並べ替える「正しい」方法は、ビューを照会するステートメントをORDER BY囲むSELECTことです。

しかし、実用的なSQLとビューの使用法が比較的新しいので、なぜこれが設計によって行われるの理解したいと思います。履歴を正しく追跡していれば、これはかつて可能であり、SQL Server 2008などから明示的に削除されました(正確なバージョンについては引用しないでください)。

ただし、Microsoftがこの機能を削除した理由について私が思い付くことができる最も良い理由は、「ビューはデータの並べ替えられていないコレクション」だからです。

ビューをソートしない理由に関して、論理的で適切な理由があると思います。ビューが単なるフラット化されたデータのコレクションになれないのはなぜですか?なぜ特別にソートなのですか?ソートされたビューを持つことは完全に直感的であると思われる状況(少なくとも私にとって/ IMHO)を思い付くのはそれほど難しくないようです。


2
最初の答えは完璧です。ビューを注文したい場合は、なぜこれをしないのかをお勧めします。[コラム] [YourView]秩序[列]の中から選択
ゼイン・

短い答え:「ORDER BYがテーブルに属さないのと同じ理由で。」
ypercubeᵀᴹ

回答:


38

(もちろん、インデックス付きビューは別として。)

ビューはマテリアライズされません-データは保存されないので、どのようにソートできますか?ビューはSELECT、パラメータなしのを含むストアドプロシージャのようなものです。データを保持せず、クエリの定義を保持するだけです。ビューへのさまざまな参照にはさまざまな方法で並べ替えられたデータが必要になる可能性があるため、これを行う方法は、テーブルから選択するのと同じように、定義によって行の並べ替えられていないコレクションでもあり、外部クエリに順序を含めることです。

また、歴史について少し洞察を与えるために。を含めない限り、ビューを配置することはできません。この場合、どの行がどのように表示されるかではなく、によってどの行が含まれるかが決まります。それはちょうどその場合は、SQL Server 2000でこれを起こったか、オプティマイザはかなり単純化され、それが一致したことをソートして計画を生産することになりました、。しかし、この動作は保証も文書化されていません- 観察に基づいているだけで、これは悪い習慣です。SQL Server 2005が登場したとき、オプティマイザーの変更によりさまざまなプランや演算子が使用されるようになったため、この動作が「破壊」され始めました。ORDER BYTOPORDER BYTOPTOP100 PERCENT{some number >= number of rows in the table}TOP/ORDER BYTOP / ORDER BYもしそうなら完全に無視されるでしょうTOP 100 PERCENT。一部の顧客はこれについて非常に大声で不満を述べたため、Microsoftはトレースフラグを発行して古い動作を回復しました。フラグを使用したくないので、フラグが何であるかを説明しません。意図が正しいことを確認したいです。予測可能なソート順が必要な場合ORDER BYは、外部クエリで使用します。

要約し、あなたが述べたポイントを明確にするために:マイクロソフトは何も削除しませんでした。彼らは製品を改善し、副作用として、この文書化されていない保証されていない動作の信頼性が低下しました。全体的に、私はこの製品がより良いと思います。


これは(コメントで)TOP結果セットに対してカーソル操作を実行することを述べています。そのため、明示的な順序を持つことができます。
ティムシュメルター

@TimSchmelterは、オプティマイザーがTOP 100 PERCENT / ORDER BYそれを参照してプランから完全に削除するときに役立ちません。やってみて。
アーロンバートランド

それはただの補足でした。とにかくコメントの残りの部分は次のとおりです。「SELECT TOP xトリックは、SQL Serverの将来のバージョンで廃止される予定です。そのため、まったく使用しないことが最善です。」
ティムシュメルター

@TimSchmelterそれはすでにノーオペレーションです。既存のコードを大量に壊してしまうので、新しいバージョンですぐに動作しなくなるとは思いません。
アーロンバートランド

2
@TimSchmelterの順序は行の順序についてではなく、行内の列の順序についてです。SQL Serverでは、行の物理的な実装が非常に明白であるため、通常、行がタプルであるとは言いません(表には、定義した順序で列がリストされます)。
アーロンバートランド

9

ビューのソートが許可された場合、ここでの結果の順序はどうでしょうか?

CREATE VIEW dbo.V1
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number ASC

GO

CREATE VIEW dbo.V2
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number DESC

GO

SELECT *
FROM   dbo.V1
       JOIN dbo.V2
         ON V1.number = V2.number 

私はこの点を理解していません。データベースビューを作成する代わりに、通常のSQLクエリを作成できます。それでは、その場合の結果の順序はどうでしょうか?感謝
HQT

7

1つの可能性は、競合する並べ替えを回避することです。ビューが1つの順序で並べ替えられ、そのビューの選択が別の順序で並べ替えられている場合(ビューの並べ替えを認識しない)、パフォーマンスが低下する可能性があります。したがって、ソート要件はユーザーに任せる方が安全です。

別の理由として、並べ替えにはパフォーマンスコストが伴うため、並べ替えが必要なのは一部のユーザーだけであるときに、ビューのすべてのユーザーにペナルティを科す理由です。


5

ANSI SQLでは、ORDER BYさまざまな理由で最も外側のクエリのみが許可されます。1つは、副選択/ビュー/ CTEが別のテーブルに結合され、外側のクエリにORDER BYそれ自体がある場合です。

SQLサーバーはビュー内でそれを決してサポートしていません(TOP 100 PERCENT私の意見では、ほとんどがバグを引き起こしているを使用してそれをだましていない限り)。

たとえバグを引き起こしたとしても、結果は信頼できるものではなく、ソートは常に期待どおりに行われたとは限りませんでした。

完全な技術的説明については、クエリオプティマイザーチームによるこのブログ投稿を参照してください

このコードのデフォルトのプラン実装では、TOP操作の実行の一部として行がソートされます。多くの場合、これは結果が並べ替えられた順序で返されることを意味し、これにより顧客は行が並べ替えられるという保証があると信じるようになりました。これは実際にはそうではありません。行をソートされた順序でユーザーに返したい場合は、最も外側のクエリブロック(ANSIごと)でORDER BYを使用して、出力の表示順序を保証する必要があります。


3

ビューは、クエリの結果によって内容が決定されるテーブルのように動作します。

テーブルには順序がありません。それらは単なる列の袋です。

したがって、ビューにも順序はありません。ただし、特定のORDER内の行を選択することで並べ替えることができます。


1
テーブルは行の単なる袋です -そして、viwesは仮想行の仮想的な袋です-ビューは「存在しません」-たとえばデータが保存されていません-それらは単に「クエリの定義を保存しました」基本的に。
marc_s

1
+1テーブルとビューの同等性は、ビューに「順序」を含めるべきではない主な理由のようです
-miracle173

1
「ビューはテーブルのように動作します」。「ビューはベーステーブルのように動作します。ビューはテーブルです。」
ypercubeᵀᴹ

-2

まだ与えられていない答えの1つは、「order by」が述部のプッシュを妨げ、パフォーマンスに大きく影響する可能性があるということです。

一例として、大量のデータセットを上位10件/注文済みの10行の概要にまとめるビューがあります。

select * from TopOrderedView; -- Ordered 10 line summary in 5s

強力な述語を使用した同じケースの場合:

select * from TopOrderedView where <condition>; -- Ordered 2 line summary in still 5s

top / order byが述語をパイプラインのより早い段階で実行することをブロックしているため、依然として同じ時間がかかります。これにより、不要な行が処理される可能性があり、計画は述語のないものと同様になります。

注文の前にプッシュを行うかどうかは、実際には開発者の選択であり、答えを変えることができます。ほとんどの場合、プッシュは論理的な意図です。

「トップ100パーセント」を使用すると、論理的に述語プッシュが可能になりますが、実装は残念ながらこの場合の「order by」を無視し、意図を無効にします。

実際の使用例では、エンジンが「プルバイオーダー」を実行するのが良い妥協案です。 これにより、ビュー内で「順序」を指定できるようになり(トップ100パーセントまたはトップなし)、その順序は、明示的な順序なし、結合なし、集約なし、なしでビューが直接選択された場合にのみ使用されますビューの連鎖など。上記の両方のケースは、この単純なモデルでサポートできます。


-6

次の後に照会されたときに順序を保持し、順序を保持するビューを作成できます。

上位99.999999999999パーセントを選択*から.....並べ替え


1
どうしてSELECT TOP 100 PERCENT ...
マックスヴァーノン

2
@Maxはおそらくこのトリックに似ています -それは良い考えではありません。
アーロンバートランド

合意、@ AaronBertrand-99.99999999999を使用する必要がないことに注意してください:
Max Vernon
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.