如何优化存储过程?

时间:2013-02-04 07:05:13

标签: sql sql-server sql-server-2008

以下是我的存储过程。

ALTER PROCEDURE [GetHomePageObjectPageWise]
       @PageIndex INT = 1
      ,@PageSize INT = 10
      ,@PageCount INT OUTPUT
      ,@AccountID INT
      ,@Interests Varchar(3000)
AS
BEGIN
      SET NOCOUNT ON;



      SELECT StoryID
      , AlbumID
      , StoryTitle
      , CAST(NULL as varchar) AS AlbumName
      , (SELECT URL FROM AlbumPictures WHERE (AlbumID = Stories.AlbumID) AND (AlbumCover = 'True')) AS AlbumCover
      , Votes
      , CAST(NULL as Int) AS PictureId
      , 'stories' AS tableName
      , (SELECT CASE WHEN EXISTS (
            SELECT NestedStories.StoryID FROM NestedStories WHERE (StoryID = Stories.StoryID) AND (AccountID=@AccountID)
        )
        THEN CAST(1 AS BIT)
        ELSE CAST(0 AS BIT) END) AS Flag
      , (SELECT UserName FROM UserAccounts WHERE Stories.AccountID=UserAccounts.AccountID) AS Username

INTO #Results1
FROM Stories WHERE FREETEXT(Stories.Tags,@Interests) AND AccountID <> @AccountID AND IsActive='True' AND Abused < 10

我在存储过程中还有7个SELECT语句(不包括在简短的问题中)类似于SELECT StoryID语句,我UNION ALL喜欢这个

SELECT * INTO #Results9 FROM #Results1
UNION ALL
SELECT * FROM #Results2
UNION ALL
SELECT * FROM #Results3
UNION ALL
SELECT * FROM #Results4
UNION ALL
SELECT * FROM #Results5
UNION ALL
SELECT * FROM #Results6
UNION ALL
SELECT * FROM #Results7
UNION ALL
SELECT * FROM #Results8

SELECT ROW_NUMBER() OVER
            (
                  ORDER BY [tableName] DESC
            )AS RowNumber
            , * INTO #Results
            FROM #Results9


      DECLARE @RecordCount INT
      SELECT @RecordCount = COUNT(*) FROM #Results

      SET @PageCount = CEILING(CAST(@RecordCount AS DECIMAL(10, 2)) / CAST(@PageSize AS DECIMAL(10, 2)))


      SELECT * FROM #Results
      WHERE RowNumber BETWEEN(@PageIndex -1) * @PageSize + 1 AND(((@PageIndex -1) * @PageSize + 1) + @PageSize) - 1

      DROP TABLE #Results
      DROP TABLE #Results1
      DROP TABLE #Results2
      DROP TABLE #Results3
      DROP TABLE #Results4 
END

返回结果大约需要6秒钟。我该如何改进这个存储过程?我对存储过程知之甚少。

3 个答案:

答案 0 :(得分:0)

where子句IsActiveAccountIDAbused中的列上提升非聚集索引。

答案 1 :(得分:0)

好吧,你只能通过删除临时表来优化它。你的方法很糟糕,因为它是一个存储过程(因此SP部分完全不相关),但是因为你做了很多临时表的事情,迫使线性执行并使查询优化器难以找到更好的一天前进

在这种特殊情况下,可能是你的数据库设计可能非常糟糕(为什么#result 1到#result 8开始)然后你在每个存储过程中都有大量的“复制到临时表”。 / p>

SQL中的查询优化工作“语句逐语”,并且语句之间的执行永远不会并行 - 所以临时表的东西真的在这里遇到了你的方式。摆脱临时表。

答案 2 :(得分:0)

永远不要直接使用SELECT * INTO #temp 代替 始终创建#temp表然后INSERT INTO #temp 这将使查询执行时间减少70%

虽然创建具有精确结构的#temp表可能会令人沮丧, 所以这里有一个捷径:这将一次执行

使用调用查询中的SELECT * INTO tableName创建dbo.tableName 然后 sp_help TableName将提供结构。 然后在Store Procedure中创建#temp表。

我已经为我们的一个客户端优化了查询,这个客户端需要45分钟才能执行,只需要用这个逻辑替换它工作了!!! 现在需要5分钟!!