Reputation: 2769
IN SQL SERVER 2008.
I have a table having huge rows. I implemented paging using row_number. But I think it isn't effective cost.
The Number of Executions => 15005. If I change 15005 to 150005 then, The number of Excutions increases to 150005.
Is it ok? Is there any method reducing this number of excutions?
This is my query
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
and Table info
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]
Upvotes: -1
Views: 583
Reputation: 49
You might get better results using OFFSET/FETCH with the following syntax (Assuming SQL Server 2012 or higher):
;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;
Here is an excellent article about the performance and use of this approach: http://sqlperformance.com/2015/01/t-sql-queries/pagination-with-offset-fetch
Adding an alternative for 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)
Upvotes: 0