以下是我的存储过程。
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秒钟。我该如何改进这个存储过程?我对存储过程知之甚少。
答案 0 :(得分:0)
在where
子句IsActive
,AccountID
和Abused
中的列上提升非聚集索引。
答案 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分钟!!