2

以下是我的存储过程。

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

SELECT在存储过程中还有 7 个语句(为简洁起见不包括在问题中),类似于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 秒。我该如何改进这个存储过程?我对存储过程知之甚少。

4

3 回答 3

0

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

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

CREATE dbo.tableName 通过使用 SELECT * INTO tableName from Your calling query 然后 sp_help TableName 将提供结构。然后在 Store Procedure 中创建 #temp 表。

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

于 2013-02-04T07:35:26.770 回答
0

好吧,您只能通过摆脱临时表来优化它。您的方法很糟糕,不是因为它是一个存储过程(因此 SP 部分完全无关紧要),而是因为您做了很多临时表的东西,这些东西会强制线性执行并使查询优化器很难找到更好的日子继续前进.

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

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

于 2013-02-04T07:13:59.370 回答
0

where在子句、IsActiveAccountID中的列上引发非聚集索引Abused

于 2013-02-04T07:12:38.723 回答