[英]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
子句IsActive
, AccountID
和Abused
列上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.