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 方式则可以解决。

 

posted @ 2012-07-19 08:36  杨伟明  阅读(467)  评论(0编辑  收藏  举报