2009-08-06 21 views
1

このようなクエリが潜在的に最適化できるかどうかは疑問です。 私はそれを大幅に簡略化しました。そして、あなたはそれを見ることができます。SQL Server 2005のSQLクエリ最適化(CTE + range関数)

with Rec (Id,Name,ParentId) 
as 
(
    select Id,Name,ParentId from Departments where ParentId is null 
    union all 
    select d.Id, d.Name, d.ParentId from Departments d join Rec r on 
    (d.ParentId=r.Id) 
) 
select q.* from (
select ROW_NUMBER() OVER (ORDER BY r.Id DESC) AS [ROW_NUMBER], r.* from Rec r 
) as q 
where q.[ROW_NUMBER] between 100 and 200 

どのようなことが行われているのかは、必要な部門を階層的に照会し、その範囲を調べることです。

私は巨大な実行計画に終わり、別の方法で実行できるかどうか疑問に思っています。

ありがとうございます。

答えて

1

私はそれが少し良く次の仮定与えられた可能性がありquess:あなたがテーブル から(列のほとんどを)大量のデータを取得ParentIdは

  • によって適切なインデックスを持って

    1. できること:ioサブシステムの負荷を減らすために、最初にIdのリストを構成し、それらをページングします(RowNumberでフィルタリングします)。これにより、上記の2つの前提を前提として、ParentIdによるインデックスの処理が効果的に実行されます。

      だからここに私の提案はそう言って「一人で」です:

      with Rec (Id,ParentId) 
      as 
      (
          select Id,ParentId from Departments where ParentId is null 
          union all 
          select d.Id, d.ParentId from Departments d join Rec r on 
          (d.ParentId=r.Id) 
      ), 
      Paged 
      as 
      (
          select * from (
           select ROW_NUMBER() OVER (ORDER BY r.Id DESC) AS [ROW_NUMBER], r.* from Rec r 
          ) as q 
          where q.[ROW_NUMBER] between 100 and 200 
      ) 
      select * 
      from 
          Paged 
          inner join Departments d on d.Id = Paged.Id 
      
  • +0

    アレックス、助けに感謝します。私はすでに私のParentIdのインデックスを作成しています。あなたのオプションは0.21のサブツリーコストを生成しますが、私のものは0.17です。 – Valentin

    +0

    それは起こります(提案された変更は役に立たない)。 私はちょうど疑問に思っています:この単純化されたケースまたは元の(複雑な、現実の)クエリのサブツリーのコストを比較しましたか?私は、結果が大きく異なると思う。 – AlexS