SQL 分页查询的几种方式
最近维护一个老项目,项目需要分页取数据,之前很久都用EF框架开发,突然要用SQL分页有点茫然,于是总结了一些SQL Server SQL分页的思路,以便加深记忆。
一:用top排序的方式
1 DECLARE @PageSize INT = 20 2 DECLARE @PageIndex INT = 2 3 4 SELECT TOP ( @PageSize ) 5 * 6 FROM ( SELECT TOP ( @PageSize * @PageIndex ) 7 * 8 FROM test 9 ORDER BY UserId ASC 10 ) table1 11 ORDER BY table1.UserId DESC
二:用字段 not in的方式
1 DECLARE @PageSize INT = 20 2 DECLARE @PageIndex INT = 2 3 4 SELECT TOP ( @PageSize ) 5 * 6 FROM dbo.test 7 WHERE UserId NOT IN ( SELECT TOP ( @PageSize * ( @PageIndex - 1 ) ) 8 UserId 9 FROM dbo.test 10 ORDER BY UserId ASC ) 11 ORDER BY dbo.test.UserId ASC
三:用字段大小范围的判断的方式
1 DECLARE @PageSize INT = 20 2 DECLARE @PageIndex INT = 1 3 4 SELECT TOP ( @PageSize ) 5 * 6 FROM dbo.test 7 WHERE UserId > ( SELECT ISNULL(MAX(UserId), 0) 8 FROM ( SELECT TOP ( @PageSize * ( @PageIndex - 1 ) ) 9 * 10 FROM dbo.test 11 ORDER BY UserId ASC 12 ) table1 13 ) 14 ORDER BY dbo.test.UserId ASC
四:row_number 方式
1 DECLARE @PageSize INT = 20 2 DECLARE @PageIndex INT = 2 3 4 DECLARE @Start INT = @PageSize * ( @PageIndex - 1 ) + 1 5 DECLARE @End INT = @PageSize * @PageIndex 6 7 SELECT * 8 FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY UserId ) AS RowNumber , 9 * 10 FROM dbo.test 11 ) table1 12 WHERE RowNumber BETWEEN @Start AND @End
总结:以上四种方式自己没有亲测具体的查询效率,根据网上的说法,第四种方式的效率应该是最慢的,但它也是最通用的,因为前三种方式必须有可排序的字段,如果没有可排序的字段比如(GUID 主键),这时用row_number 方式则可以解决。