2016-08-25 159 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中的选项。 –