如何优化此查询

时间:2013-04-26 23:41:29

标签: sql sql-server database performance database-indexes

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 

有没有办法优化此查询?关于索引或方式递归的任何建议都会有所帮助

1 个答案:

答案 0 :(得分: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