微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SQL分页的最佳方法

如何解决SQL分页的最佳方法

我有#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,@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

结果:

enter image description here

在大数据上工作非常缓慢。我使用sql 2012女士。

解决方法

您可以使用OFFSET&FETCH NEXT功能, OFFSET关键字仅从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

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

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

要获得更深入的了解和性能,请阅读enter image description here文章

,

基于集合的操作性能更好。避免逐行处理。

我们可以使用数据库分配的row_number并除以我们希望每页生成页面索引的记录数。如果我们截断/(舍入并消除小数点),我们将获得所需的页面索引。

类似的东西:

SELECT ID,SomeName,round(ROW_NUMBER() OVER(ORDER BY SomeName ASC)/5,1) AS PageIndex
FROM #temp
ORDER BY PageIndex,SomeName
  • 5代表每“页”的记录数
  • 0,因为我们不在乎小数点,但我们不希望在舍去小数点前进行舍入。
  • 1截断为0个小数(不舍入)。

我假设您知道可以将其包装在CTE中并添加where子句以获取所需的特定页面

,

当您正在寻找最佳的分页方法时,您正确地说,对于大量数据,您的解决方案很慢,您必须根据用户请求一次获取一页数据。

当用户单击第2页时,您将仅获得并非第2页的记录。

这是示例代码

declare @PageNumber int = 2; -- just an example,will come from parameter
declare @PageTo int = @PageSize * @PageNumber;
declare @PageFrom int = @PageTo - @PageSize;

    SELECT
        Id,@PageNumber
    FROM #temp
    WHERE Id > @PageFrom AND Id <= @PageTo

drop table #temp

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。