优化嵌套查询以加入

时间:2018-06-21 10:28:51

标签: sql sql-server join query-optimization

我在function中有下面的查询,该查询返回count-

 SELECT @CommentCount  = COUNT(1)               
 FROM cs_posts              
 WHERE PostLevel IN (2,3) AND IsApproved=1  AND ThreadId=(SELECT ThreadId FROM Cs_Posts WHERE PostId=@PostID)          

 RETURN @CommentCount   

improve the performance,我需要optimize

我还使用了function in SP次,此功能被调用36次[见下文]-

INSERT INTO @TempPostIds (RowID,PostID)                                           
SELECT TOP 36                      
ROW_NUMBER() OVER(ORDER BY CASE 
WHEN @sortBy  ='comments' THEN ISNULL(dbo.GetCommentCountForPost(CP.PostID),0) END DESC, <---here the function is called
CASE WHEN @sortBy = 'views' THEN IsNull(MAVC.ViewCount,CP.TotalViews) END DESC,
CASE WHEN @sortBy='date' THEN CP.PostDate END DESC),         
CP.PostID

 from CS_Posts as CP with (nolock)                                          
 inner join NewsletterDetails AD  (nolock ) on CP.PostID = AD.PostID                                          
 Inner Join cs_Threads CT (NOLOCK) on CP.ThreadID = CT.ThreadID                                          
 Inner Join MapNewsletterPosts MM (NOLOCK)on MM.PostID = AD.PostId                                          
 Inner Join NewsLetter NW (NOLOCK) ON NW.ID = MM.ID 
 LEFT OUTER JOIN PostViewCount MAVC (NOLOCK) ON CP.PostID = MAVC.PostID                                          
 WHERE                                          
 CP.isapproved =1                                          
 AND CP.PostStatus = 7                                           
 AND CP.SectionID in(95,199)  
 AND AD.IncludeInArticles=1                                           
 AND AD.NewsletterDate <= DATEADD(day,-7, GETDATE())

请帮助并提出建议。

3 个答案:

答案 0 :(得分:1)

这回答了问题的原始版本。

对于此查询:

SELECT @CommentCount  = COUNT(1)               
FROM cs_posts              
WHERE PostLevel IN (2, 3) AND
      IsApproved = 1  AND
      ThreadId = (SELECT p2.ThreadId FROM Cs_Posts p2 WHERE p2.PostId = @PostID);

您要在cs_posts(PostId, ThreadId)cs_posts(IsApproved, PostLevel, ThreadId)上建立索引。

答案 1 :(得分:1)

不确定我是否正确理解了您的功能(尤其是没有表结构),但是我认为不需要嵌套查询:

SELECT @CommentCount  = COUNT(1)               
FROM cs_posts              
WHERE PostLevel IN (2,3) AND IsApproved=1  AND PostId=@PostID
RETURN @CommentCount

祝你好运!

答案 2 :(得分:1)

使用TVF而不是使用标量函数:

CREATE FUNCTION dbo.GetCommentCountForPost_tvf (@PostID int) RETURNS TABLE
AS RETURN

    SELECT COUNT(*) AS CommentCount
    FROM cs_posts c
    WHERE c.PostLevel IN (2,3)
      AND c.IsApproved = 1
      AND EXISTS (SELECT 1 FROM Cs_Posts e WHERE e.PostId = @PostID AND e.ThreadId = c.ThreadId);

然后,在您的SELECT中将ISNULL(dbo.GetCommentCountForPost(CP.PostID),0)更改为ISNULL(GCC.CommentCount,0)并将以下内容添加到您的FROM中:

CROSS APPLY dbo.GetCommentCountForPost_tvf(CP.PostID) GCC