2012-01-18 22 views
4

このクエリを考えてみてください:ROW_NUMBER()実行計画

SELECT num, 
    * 
FROM (
     SELECT OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate, 
       ShippedDate, 
       ROW_NUMBER() 
       OVER(ORDER BY OrderID) AS num 
     FROM Orders 
    ) AS numbered 
WHERE NUM BETWEEN 0AND 100 

私はこのクエリを実行し、実行計画を取得するとき、それはこのようなものだ:

​​

私は

を知りたいです

1)SQL Server 2008がクエリにROW_NUMBER()を追加するために渡す手順は?

2)なぜ実行計画の最初のステップでClustered Index Scanがあるのですか?

3)なぜフィルタリングコストは2%ですか?私はなぜ適切なデータを取得するためにSQL Serverは、テーブルスキャンを実行しないのですか? ROW_NUMBER()はインデックスを作成しますか?

+0

なぜ私はいくつかの1つの投票-1または近くに投票!!!!この質問のどの部分が間違っていますか? – Arian

+0

IMHOこれはローカライズされた*ではありません。これは、ほとんどのSQLプログラマが理解できる非常に簡単な例を使用する 'ROW_NUMBER()'の実行計画についての確かな質問です。 – Yuck

+0

私は理解していません.ROW_NUMBER()はSQLプログラミングに属していませんか?ユーザーが理解できるようにするための例を示します。 – Arian

答えて

2
  1. 計画のセグメント/シーケンスプロジェクトの部分は、ROW_NUMBER()の使用に関連しています。

  2. 内部SELECTにWHERE句がないため、クラスタ化インデックススキャンがあるため、テーブルのすべての行を返す必要があります。

  3. フィルタは外側のSELECTのWHERE句に関連しています。クエリの「計算スカラー」の部分がrow_numberが作成されていることを

+0

+1。 – Yuck

+0

約3. ROW_NUMBER()が作成され、1000000レコードがあり、999900から1000000レコードが必要な場合、結果を得るためにswlサーバーがすべてのレコード(1から1000000まで)をループしますか? – Arian

+0

@Rozhin - そうです。 'ROW_NUMBER'ページングクエリは、多くの場合、書き換えによって改善することができます。例えば、QOは現在狭いインデックスを使用して '999,900'レコードを見つけて最後の100レコードだけのより広いカバーインデックスに切り替えることを検討することはできません。 [Segment and Sequence Project Iterators]の説明(http://sqlblog.com/blogs/paul_white/archive/2010/07/28/the-segment-and-sequence-project-iterators.aspx) –

0
  1. Ordersからすべての行を選択しているため、番号を付けて1-100を選択します。それはテーブル(またはこの場合はクラスタ化されたインデックス)です。とにかくそれをスライスします。
  2. いいえ、インデックスはオンザフライでは作成されません。サブクエリで順序が戻ってこないので、行をチェックする必要があります。
関連する問題