2016-08-25 158 views
-1

SQL Server 2008中使用SQL Server ROW_NUMBER分頁時在執行計劃執行的太多數

我有巨大的行的表。我使用row_number實現分頁。但我認爲這不是有效的成本。

執行計劃 enter image description here

處決的人數=> 15005. 如果我更改到15005,然後150005,的Excutions增加至150005.

人數是否確定?有什麼方法可以減少這種數量的刺激物嗎?

這是我的查詢

SELECT * 
FROM 
(
    select *, ROW_NUMBER() OVER(ORDER BY send_time) as row_num 
    FROM [dbo].[GlobalMessage] 
    WHERE active =1 
) as T 
WHERE row_num >= 15000 and row_num < 15005 

和表信息

CREATE TABLE [dbo].[GlobalMessage](
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [active] [int] NOT NULL, 
    [message] [nvarchar](200) NOT NULL, 
    [send_time] [int] NOT NULL, 
CONSTRAINT [PK_GlobalMessage] PRIMARY KEY CLUSTERED 
(
    [id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

CREATE NONCLUSTERED INDEX [NonClusteredIndex-20160823-125945] ON [dbo].[GlobalMessage] 
(
    [active] ASC, 
    [send_time] DESC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 

回答

0

你可能會得到更好的結果使用OFFSET /語法如下(假設SQL Server 2012中或更高版本)獲取:

;WITH pg AS 
(
    SELECT [key_column] 
    FROM [dbo].[GlobalMessage] 
    ORDER BY send_time 
    OFFSET @PageSize * (@PageNumber - 1) ROWS 
    FETCH NEXT @PageSize ROWS ONLY 
) 
SELECT t.* 
    FROM [dbo].[GlobalMessage] AS t 
    INNER JOIN pg ON t.[key_column] = pg.[key_column] -- or EXISTS 
    ORDER BY send_time; 

這是一篇關於這種方法的性能和使用的優秀文章:http://sqlperformance.com/2015/01/t-sql-queries/pagination-with-offset-fetch

添加爲SQL Server 2008的替代:

declare @rowsPerPage as bigint; 
declare @pageNum as bigint; 
set @rowsPerPage=25; 
set @pageNum=10; 

With SQLPaging As ( 
    Select Top(@rowsPerPage * @pageNum) ROW_NUMBER() OVER (ORDER BY ID asc) 
    as resultNum, * 
    FROM [dbo].[GlobalMessage] 
    WHERE active =1 
    ) 
select * from SQLPaging with (nolock) where resultNum > ((@pageNum - 1) * @rowsPerPage) 
+0

我不能使用OFFSET/FETCH方法。應該是SQL SERVER 2008 –

+0

加入SQL Server 2008中的選項。 –