Sql 分页的最佳方式

Vou*_*cik 0 sql t-sql database sql-server sql-server-2012

我有#temp 表,我需要对该表中的所有数据进行分页。表格分页的最佳方式是什么?

create table #temp (
    Id int
    ,SomeName nvarchar(100)
)

create table #tempPage (
    Id int
    ,SomeName nvarchar(100)
    ,PageIndex int
)
--Test data
insert #temp (Id, SomeName) values
(1,'A'),
(2,'B'),
(3,'C'),
(4,'D'),
(5,'F'),
(6,'G'),
(7,'H'),
(8,'A1'),
(9,'B1'),
(10,'C1'),
(11,'D1'),
(12,'F1'),
(13,'G1'),
(14,'H1');

--Page size
declare @PageSize int = 5

--Max page count
declare @MaxPages float = (
    select
        case when count(Id)%@PageSize>0 then count(Id)/@PageSize+1 else count(Id)/@PageSize end
    from #temp
)

declare @PageFrom int = 0

declare @CurrentPage int = 1

while @CurrentPage <= @MaxPages
begin
    insert #tempPage (Id, SomeName, PageIndex)
    SELECT
        Id, SomeName, @CurrentPage
    FROM #temp
    ORDER BY id OFFSET @PageFrom ROWS
    FETCH NEXT @PageSize ROWS ONLY;
    set @PageFrom = @PageFrom + @PageSize
    set @CurrentPage = @CurrentPage + 1

end

select * from #tempPage

drop table #temp
drop table #tempPage
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述

它在大数据上的工作速度非常慢。我使用Ms Sql 2012。

avi*_*oni 5

您可以使用 OFFSET & FETCH NEXT 功能,OFFSET 关键字仅带来 from row_number 和 FETCH NEXT 带来直到。举个例子:

 USE AdventureWorks2008R2
    GO
    SELECT 
      BusinessEntityID
      ,PersonType
     ,FirstName + ' ' + MiddleName + ' ' + LastName 
    FROM Person.Person
     ORDER BY BusinessEntityID ASC
      OFFSET 100 ROWS 
      FETCH NEXT 5 ROWS ONLY
    GO
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以使用分页参数,例如:

SELECT
  BusinessEntityID
 ,PersonType
 ,FirstName + ' ' + MiddleName + ' ' + LastName 
FROM Person.Person
 ORDER BY BusinessEntityID
  OFFSET (@PageNo - 1) * @RowCountPerPage ROWS
  FETCH NEXT @RowCountPerPage ROWS ONLY
GO 
Run Code Online (Sandbox Code Playgroud)

为了更深入地理解和性能,你可以阅读这篇文章 - Pagination with OFFSET / FETCH : A better way文章