私はSQL Server 2008のDBを1.4秒で実行するクエリを持っています。それから私は、このテンプレートを使用したサブクエリを実行しようとしました:私は低い数字にXとYを設定した場合MSSQLのスローCTEサブクエリ
;with __myResults as (
... my initial query ... already has a column:
row_number() over (ORDER BY ...) as RowNum
)
select * from __myResults where RowNum between X and Y
、それがうまく実行されます。約0.3秒かかります。 XとYを高い数値に設定すると、最初のクエリよりも悪化します。私がXとYを増やすと、実行時に絶えず増加します。
どうすればいいですか? (「:nは%コスト」だけを見て)私はこれをどのようにデバッグするん
を私は実行計画を比較されて実行しようとしましたが、彼らは同じであった何
?どこに問題があるのか分かりますか?
私はまた、次のことを試してみました:
where RowNum > highNumber
は速いです!一方、
where RowNum > highNumber and RowNum < highNumber + 10
が遅い。最後に:
where RowNum < highNumber
は非常に遅いです(6秒)。
更新
私は、一時テーブルに結果を置くことになりました。その後、フィルタリングを行います。このように速いようです。
CTEは、選択クエリで参照するときにのみ呼び出されます。 where句のRowNumを低く設定すると、それが一致するまで選択するだけで済みます。増加すると、より多くの作業が必要になることを意味します。 – dbajtr
row_numberを使用するメソッドが結果セットを分割するために使用されているようです。 [offset fetch next](https://stackoverflow.com/questions/37184267/in-sql-server-2014-order-by-clause-with-offset-fetch-next-returns-weird-results)の使用を検討しましたか? ? SQL Server 2012以降でのみ使用可能です。 – LukStorms
結果セットでCTEが実行されるため、セットが大きいほどクエリが遅くなります。 (したがって、「ウィンドウ関数」という名前)。いくつかの回避策がありますが、実際のクエリに依存しています。しかし私が試みる最初のことは、結果を含むrownumberを(テーブル変数ではなく)一時テーブルに選択し、それをCTEの代わりに基礎として使用することです。前述のように、TOPやNOT INを選択したり、ユニオンと自己結合を使用して問合せを最小限に抑えたり、索引を最適化したりするなどの他の手法もあります。しかし実際の問い合わせがなければ、アドバイスが難しいです –