简体   繁体   English

如何优化存储过程?

[英]How to optimize stored procedures?

Following is my Stored Proc. 以下是我的存储过程。

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

I have 7 more SELECT Statements (not included in the question for brevity) in the Stored Proc similar to SELECT StoryID statement, which i UNION ALL like this 我在存储过程中还有另外7条SELECT语句(为简洁起见未包括在内),类似于SELECT StoryID语句,i 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

This takes around 6 seconds to return the result. 这大约需要6秒钟才能返回结果。 How can i improve this stored proc? 如何改善此存储过程? I have very little knowledge about stored procedures. 我对存储过程了解很少。

where子句IsActiveAccountIDAbused列上IsActive非聚集索引。

Well, you can only optimize it by getting rid of the temporary tables. 好吧,您只能通过摆脱临时表来对其进行优化。 Your approach sucks not because it is a stored procedure (so the SP part is simply totally irrelevant) but because you do a lot of temporary table stuff that forces linear execution and makes it hard for the query optimizer to find a better day to go forward. 您的方法之所以糟糕,不是因为它是一个存储过程(因此SP部分完全不相关),而是因为您做了很多临时表的工作,这些工作迫使线性执行,并使查询优化器很难找到更美好的一天。

In this particular case, it may be that your db design may be horrifically bad (why #result 1 to #result 8 to start with) and then you have tons of "copy into temp table" on every stored procedure. 在这种情况下,您的数据库设计可能很糟糕(为什么从#result 1到#result 8开始),然后在每个存储过程中都有大量“复制到临时表”。

Query Optimization in SQL works "statement by statement" and execution is never paralleled between statements - so the temp table stuff really gets into your way here. SQL中的查询优化以“按语句陈述”的方式工作,并且语句之间的执行从未并行-因此,临时表在这里确实很麻烦。 Get rid of the temp tables. 摆脱临时表。

Never ever use directly SELECT * INTO #temp INSTEAD Always create #temp tables then INSERT INTO #temp this will reduce query execution time by 70% 永远不要直接使用SELECT * INTO #temp INSTEAD始终创建#temp表,然后插入INSERT #TOTEMP这将减少70%的查询执行时间

Though it might be frustration to create #temp table with exact structures, so here is a short cut for that:This will be once performed 尽管创建具有精确结构的#temp表可能会令人沮丧,但是这是一个捷径:这将一次执行

CREATE dbo.tableName by using SELECT * INTO tableName from Your calling query then sp_help TableName will provide structures. 通过从您的调用查询中使用SELECT * INTO tableName创建dbo.tableName,然后sp_help TableName将提供结构。 Then create #temp table in Store Procedure. 然后在存储过程中创建#temp表。

I have optimized query for one of our client which was taking 45 minutes to execute, just replaced with this logic It worked !!! 我已经优化了对我们的一个客户端的查询,该查询花了45分钟才能执行,只是被这种逻辑所取代! Now it takes 5 Minutes !! 现在需要5分钟!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM