SQL Server stored procedure running very slow

时间:2018-03-22 23:42:14

标签: sql-server stored-procedures optimization

My scenario: I have a table with 10M+ rows & 10 columns (Table name: Giggerdata). I have my stored procedure designed such that when I pass two parameters (pageNumber, pageSize), it divides the Giggerdata table records up into pages (each page having 10M/pageSize records). It will only return those records on the pageNumber passed in.

I call the stored procedure from an external service which iterates through my table in batches of 30 MB (that's the limit for the API I'm using). I would effectively iterate through this table page by page (each page having 30MB worth of records) and push that data through another API.

I need to speed this stored procedure up as it takes >3 minutes get results with pageNumber = 1 and pageSize = 400,000, which is > 1 hour to get my entire table exported through this iterative fashion (unacceptable for my application).

I've read up on stored procedure issues, and have tried altering my stored procedure to take into account the parameter sniffing; would someone be able to look at my stored procedure and determine whether I've properly implemented the local parameter solution?

Are there other measures I can take to speed things up?

My stored procedure:

ALTER PROCEDURE [dbo].[mySP]
    @pageNumber INT, 
    @pageSize INT
AS 
BEGIN
    DECLARE @locpageNumber INT, @locpageSize INT

    SELECT @locpageNumber = @pageNumber, @locpageSize = @pageSize 

    SELECT *
    FROM dbo.GiggerData
    ORDER BY Col1
        OFFSET @locpageSize * (@locpageNumber - 1) ROWS
        FETCH NEXT @locpageSize ROWS ONLY
    OPTION (RECOMPILE)
END

Test code:

DECLARE @return_value INT
EXEC    @return_value = dbo.[mySP]
            @pageNumber = 41,
            @pageSize = 500000

SELECT  'Return Value' = @return_value
GO

1 个答案:

答案 0 :(得分:0)

使用OFFSETFETCH的分页对于每个页面将逐渐变慢,因为SQL Server仍需要在有序行集的开头启动。如果GiggerData_Key是唯一的聚簇索引,则可以使用更有效的基于密钥的分页方法:

SELECT TOP (500000) *
FROM dbo.GiggerData
WHERE GiggerData_Key > @Last_GiggerData_Key_Returned
    OR @Last_GiggerData_Key_Returned IS NULL --first page
ORDER BY GiggerData_Key`;