-1
Create table #tmptble(RuleId, SubjectId, RID, Date)

Insert into #tmptble(RuleId,SubjectId, RID, Date)
Select RuleTable.RuleId, RuleTable.SubjectId, KeyTable.RID, KeyTable.ParentId
FROM RuleTable INNER JOIN KeyTable
ON KeyTable.RID = RuleTable.RID

このクエリは非常に低速です。KeyTable の RID にクラスター化インデックス、RuleTable の RuleId にクラスター化インデックス、RuleTable の RuleId+SubjectId に一意の非クラスター化インデックスがあります。(RuleTableは他にもいろいろなところで使われています)

上記のクエリで、次のようなwhere句を導入すると

Insert into #tmptble(RuleId,SubjectId, RID, Date)
Select RuleTable.RuleId, RuleTable.SubjectId, KeyTable.RID, KeyTable.ParentId
FROM RuleTable INNER JOIN KeyTable
ON KeyTable.RID = RuleTable.RID
WHERE KeyTable.RID = @RID -- @RID is passed into the storedproc

実行時間が > 50% 短縮されます。WHEREしかし、問題は、次の方法で句なしで元のテーブル結果を使用することです

 WITH ResourceTree AS
(
    SELECT
    #tmptble.RuleId AS [RuleId], 
    #tmptble.SubjectId AS [SubjectRecId], 
    #tmptble.RId AS [RId], 
    #tmptble.ParentID AS [ParentID]                     
    FROM #tmptble WHERE #tmptble.SubjectId = @SubjectId
    AND #tmptble.RId = @RId 

   UNION ALL

   -- Recursive step
       -- Note that the recursive step uses the results from original #tmptable
   SELECT
   #tmptble.RuleId AS [RuleId], 
   #tmptble.SubjectId AS [SubjectId], 
   #tmptble.RId AS [RId], 
   #tmptble.ParentID AS [ParentID]                      
   FROM #tmptble INNER JOIN ResourceTree RT
   ON RT.ParentID = #tmptble.RId 
)

SELECT *
FROM ResourceTree 

このクエリを最適化する方法はありますか? インデックスまたは再帰の実行方法に関するあらゆる種類の提案が役立ちます

4

1 に答える 1

0

これはあなたに役立つ可能性があります-

;WITH temp AS 
(
    SELECT  
          r.RuleId
        , r.SubjectId
        , r.RID
        , k.ParentId
    FROM (
        SELECT r.*
        FROM dbo.RuleTable r
        WHERE r.RID = @RID
    ) r
    JOIN dbo.KeyTable k ON k.RID = r.RID
)
, ResourceTree AS
(
    SELECT
          t.RuleId
        , [SubjectRecId] = t.SubjectId 
        , t.RId 
        , t.ParentID                  
    FROM temp t
    WHERE t.SubjectId = @SubjectId

    UNION ALL

    SELECT
          t.RuleId
        , t.SubjectId
        , t.RId
        , t.ParentID                   
    FROM temp t
    WHERE EXISTS (
        SELECT 1 
        FROM ResourceTree r 
        WHERE r.ParentID = t.RId 
    )
)
SELECT *
FROM ResourceTree 
于 2013-04-27T05:24:56.057 に答える