如何优化此查询

Posted

技术标签:

【中文标题】如何优化此查询【英文标题】:How do I optimize this query 【发布时间】:2013-04-26 23:41:29 【问题描述】:
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】:

这可能对你有帮助 -

;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 

【讨论】:

以上是关于如何优化此查询的主要内容,如果未能解决你的问题,请参考以下文章

如何优化此 SQL Server 查询 - 多个子查询

如何优化此查询...?

如何在 Postgres 中优化此查询

SQL Server - 如何优化此查询?

如何在 Firebird 2.1 中优化此查询?

如何在 MYSQL 中优化此查询?需要做啥