解决慢查询

csc*_*ear 1 t-sql sql-server-2008

我们正在为我们的网站安装一个新论坛(yaf).其中一个存储过程非常慢 - 实际上它总是在浏览器中超时.如果我在MSSMS中运行它需要将近10分钟才能完成.如果花了这么长时间,有没有办法找出这个查询的哪个部分?

查询:

DECLARE @BoardID int 
DECLARE @UserID int
DECLARE @CategoryID int = null
DECLARE @ParentID int = null

SET @BoardID = 1
SET @UserID = 2

    select 
    a.CategoryID, 
    Category        = a.Name, 
    ForumID         = b.ForumID,
    Forum           = b.Name, 
    Description,
    Topics          = [dbo].[yaf_forum_topics](b.ForumID),
    Posts           = [dbo].[yaf_forum_posts](b.ForumID),
    Subforums       = [dbo].[yaf_forum_subforums](b.ForumID, @UserID),
    LastPosted      = t.LastPosted,
    LastMessageID   = t.LastMessageID,
    LastUserID      = t.LastUserID,
    LastUser        = IsNull(t.LastUserName,(select Name from [dbo].[yaf_User] x where x.UserID=t.LastUserID)),
    LastTopicID     = t.TopicID,
    LastTopicName   = t.Topic,
    b.Flags,
    Viewing         = (select count(1) from [dbo].[yaf_Active] x JOIN [dbo].[yaf_User] usr ON x.UserID = usr.UserID where x.ForumID=b.ForumID AND usr.IsActiveExcluded = 0),
    b.RemoteURL,
    x.ReadAccess
from 
    [dbo].[yaf_Category] a
    join [dbo].[yaf_Forum] b on b.CategoryID=a.CategoryID
    join [dbo].[yaf_vaccess] x on x.ForumID=b.ForumID
    left outer join [dbo].[yaf_Topic] t ON t.TopicID = [dbo].[yaf_forum_lasttopic](b.ForumID,@UserID,b.LastTopicID,b.LastPosted)
where 
    a.BoardID = @BoardID and
    ((b.Flags & 2)=0 or x.ReadAccess<>0) and
    (@CategoryID is null or a.CategoryID=@CategoryID) and
    ((@ParentID is null and b.ParentID is null) or b.ParentID=@ParentID) and
    x.UserID = @UserID
order by
    a.SortOrder,
    b.SortOrder
Run Code Online (Sandbox Code Playgroud)

IO统计:

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'yaf_Active'. Scan count 14, logical reads 28, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'yaf_User'. Scan count 0, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'yaf_Topic'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'yaf_Category'. Scan count 0, logical reads 28, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'yaf_Forum'. Scan count 0, logical reads 488, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'yaf_UserGroup'. Scan count 231, logical reads 693, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'yaf_ForumAccess'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'yaf_AccessMask'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'yaf_UserForum'. Scan count 1, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Run Code Online (Sandbox Code Playgroud)

客户统计:

Client Execution Time   11:54:01        
Query Profile Statistics            
  Number of INSERT, DELETE and UPDATE statements    0       0.0000
  Rows affected by INSERT, DELETE, or UPDATE statements 0       0.0000
  Number of SELECT statements   8       8.0000
  Rows returned by SELECT statements    19      19.0000
  Number of transactions    0       0.0000
Network Statistics          
  Number of server roundtrips   3       3.0000
  TDS packets sent from client  3       3.0000
  TDS packets received from server  34      34.0000
  Bytes sent from client    3166        3166.0000
  Bytes received from server    128802      128802.0000
Time Statistics         
  Client processing time    156478      156478.0000
  Total execution time  572009      572009.0000
  Wait time on server replies   415531      415531.0000
Run Code Online (Sandbox Code Playgroud)

执行计划

SQL*_*ace 5

看看你在WHERE子句中使用Column = @Param OR @Param IS NULL吗?不要,它不会通过使用sp_executesql来更好地了解如何重写它.

这看起来像一个函数调用?

 left outer join [dbo].[yaf_Topic] t ON t.TopicID = [dbo].[yaf_forum_lasttopic](b.ForumID,@UserID,b.LastTopicID,b.LastPosted)
Run Code Online (Sandbox Code Playgroud)

也许你的功能搞砸了这个东西,硬编码而不是函数调用,看它是否会产生巨大的差异