创建环境:

create table pagetest
(
id int identity(1,1) not null,
col01 int null,
col02 nvarchar(50) null,
col03 datetime null
) --100万记录集(大约耗时5min)
declare @i int
set @i=0
while(@i<1000000)
begin
insert into pagetest select cast(floor(rand()*10000) as int),left(newid(),10),getdate()
set @i=@i+1
end

几种分页方式比较:

--写法1,not in/top
--每页50条,取第2015页数据
declare @begin_date datetime
declare @end_date datetime
select @begin_date = getdate()
select top 50 * from pagetest
where id not in (select top ((2015-1)*50) id from pagetest order by id)
order by id
select @end_date = getdate()
select datediff(ms,@begin_date,@end_date) as 'ms'

结果:473 ms

--写法2,not exists
declare @begin_date datetime
declare @end_date datetime
select @begin_date = getdate()
select top 50 * from pagetest
where not exists
(select 1 from (select top ((2015-1)*50) id from pagetest order by id)a where a.id=pagetest.id)
order by id
select @end_date = getdate()
select datediff(ms,@begin_date,@end_date) as 'ms'

结果:483 ms

--写法3,max/top
declare @begin_date datetime
declare @end_date datetime
select @begin_date = getdate()
select top 50 * from pagetest
where id>(select max(id) from (select top ((2015-1)*50) id from pagetest order by id)a)
order by id
select @end_date = getdate()
select datediff(ms,@begin_date,@end_date) as 'ms'

结果:343 ms

--写法4,row_number() 只支持sql2005及以上版本
declare @begin_date datetime
declare @end_date datetime
select @begin_date = getdate()
select top 50 * from
(select row_number()over(order by id)rownumber,* from pagetest)a
where rownumber>((2015-1)*50)
select @end_date = getdate()
select datediff(ms,@begin_date,@end_date) as 'ms'

结果:293 ms

以上测试在不同环境在会有略微差别,整体来说都还不错,row_number和max/top方式性能相对更好些,而row_number只支持sql2005版本及以上,所以max/top在大部分环境下会是比较好的选择。

简单将ROWNUMBER,max/top的方式封装到存储过程。

create proc [dbo].[spSqlPageByRownumber]
@tbName varchar(255), --表名
@tbFields varchar(1000), --返回字段(可以为*)
@PageSize int, --页尺寸
@PageIndex int, --页码
@strWhere varchar(1000), --查询条件(为空则无条件)
@StrOrder varchar(255), --排序条件
@Total int output --返回总记录数
as
declare @strSql varchar(5000) --主语句
declare @strSqlCount nvarchar(500)--查询记录总数主语句 --------------总记录数---------------
if @strWhere !=''
begin
set @strSqlCount='Select @TotalCout=count(*) from ' + @tbName + ' where '+ @strWhere
end
else
begin
set @strSqlCount='Select @TotalCout=count(*) from ' + @tbName
end
--------------分页------------
if @PageIndex <= 0
begin
set @PageIndex = 1
end set @strSql='Select * from (Select row_number() over('+@strOrder+') rowId,'+ @tbFields
+' from ' + @tbName + ' where 1=1 ' + @strWhere+' ) tb where tb.rowId >'+str((@PageIndex-1)*@PageSize)
+' and tb.rowId <= ' +str(@PageIndex*@PageSize) exec sp_executesql @strSqlCount,N'@TotalCout int output',@Total output
exec(@strSql)
create proc [dbo].[spSqlPageByMaxTop]
@tbName varchar(255), --表名
@tbFields varchar(1000), --返回字段(可以为*)
@PageSize int, --页尺寸
@PageIndex int, --页码
@strWhere varchar(1000), --查询条件(为空则无条件)
@StrOrder varchar(255), --排序条件
@Total int output --返回总记录数
as
declare @strSql varchar(5000) --主语句
declare @strSqlCount nvarchar(500)--查询记录总数主语句 --------------总记录数---------------
if @strWhere !=''
begin
set @strSqlCount='Select @TotalCout=count(*) from ' + @tbName + ' where '+ @strWhere
end
else
begin
set @strSqlCount='Select @TotalCout=count(*) from ' + @tbName
end
--------------分页------------
if @PageIndex <= 0
begin
set @PageIndex = 1
end set @strSql='select top '+str(@PageSize)+' * from ' + @tbName + '
where id>(select max(id) from (select top '+str((@PageIndex-1)*@PageSize)+' id from ' + @tbName + ''+@strOrder+')a)
'+@strOrder+'' exec sp_executesql @strSqlCount,N'@TotalCout int output',@Total output
exec(@strSql)

转载自:http://www.cnblogs.com/iamowen/archive/2011/11/03/2235068.html

[转]几种常见SQL分页方式的更多相关文章

  1. 几种常见SQL分页方式效率比较(转)

    http://www.cnblogs.com/iamowen/archive/2011/11/03/2235068.html 分页很重要,面试会遇到.不妨再回顾总结一下. 1.创建测试环境,(插入10 ...

  2. 几种常见SQL分页方式效率比较

    分页很重要,面试会遇到.不妨再回顾总结一下: 一:创建测试环境,(插入100万条数据大概耗时5分钟). create database DBTestuse DBTest 二:--创建测试表 creat ...

  3. 常见SQL分页方式效率比较

    结一下. 1.创建测试环境,(插入100万条数据大概耗时5分钟). ,) ) )) ),end 2.几种典型的分页sql,下面例子是每页50条,198*50=9900,取第199页数据. id id ...

  4. Spring RestTemplate中几种常见的请求方式GET请求 POST请求 PUT请求 DELETE请求

    Spring RestTemplate中几种常见的请求方式 原文地址: https://blog.csdn.net/u012702547/article/details/77917939   版权声明 ...

  5. Spring RestTemplate中几种常见的请求方式

    https://github.com/lenve/SimpleSpringCloud/tree/master/RestTemplate在Spring Cloud中服务的发现与消费一文中,当我们从服务消 ...

  6. Java几种常见的编码方式

    几种常见的编码格式 为什么要编码 不知道大家有没有想过一个问题,那就是为什么要编码?我们能不能不编码?要回答这个问题必须要回到计算机是如何表示我们人类能够理解的符号的,这些符号也就是我们人类使用的语言 ...

  7. 目前常见的三种SQL分页方式:

    --top not in方式 select top 条数 * from tablename where Id not in (select top 条数*页数 Id from tablename) - ...

  8. 8种常见SQL错误用法,你中招了吗?

    作者:db匠 来源:https://yq.aliyun.com/articles/72501 1.LIMIT 语句 分页查询是最常用的场景之一,但也通常也是最容易出问题的地方.比如对于下面简单的语句, ...

  9. 8 种常见 SQL 错误用法

    点击上方"开源Linux",选择"设为星标"回复"学习"获取独家整理的学习资料! 1.LIMIT 语句 分页查询是最常用的场景之一,但也通常 ...

随机推荐

  1. static/final

  2. Leetcode 299 Bulls and Cows 字符串处理 统计

    A就是统计猜对的同位同字符的个数 B就是统计统计猜对的不同位同字符的个数 非常简单的题 class Solution { public: string getHint(string secret, s ...

  3. lamper技能树

  4. python先序、中序、后序排序

    #encoding=utf-8 class Tree(): def __init__(self,leftjd=0,rightjd=0,data=0): self.leftjd = leftjd sel ...

  5. solr多core的处理

    有2中配置方式,一是从Solr Admin进行multi core的配置. 在Solr Admin控制台里面选择:Core Admin 选择Add Core 然后把你准备好的路径写到里面去. name ...

  6. asp.net“服务器应用程序不可用” 解决方法

    服务器应用程序不可用 您试图在此 Web 服务器上访问的 Web 应用程序当前不可用.请点击 Web 浏览器中的“刷新”按钮重试您的请求. 管理员注意事项: 详述此特定请求失败原因的错误消息可在 We ...

  7. Linear or non-linear shadow maps?

    Quote: Original post by RobMaddisonI understand that, for aliasing mitigation, it might be beneficia ...

  8. Java 时间和字符换的处理

    /** * * @param timeStr 时间字符串 * @param diff 与起始值差距,单位为毫秒 * @throws ParseException */ public String de ...

  9. 从零开始--系统深入学习IOS(使用Swift---带链接)

    这是一篇面向IOS新手的文档.同时提供一些系统知识的链接,让你系统学习IOS.它提供一些信息帮助你采用技术和编程接口来开发苹果软件产品,本人不保证会在将来更新.学习它,需要你掌握一些基本的编程知识 1 ...

  10. Putty & Ctrl+s 的魔咒

    Long long ago“ 某些旧的”哑终端“会在发送过来的数据太多,显示速度跟不上时发送一个Ctrl+s让对方等一下,然后再准备好继续显示时发送一个Ctrl+q.Putty“兼容”了这个特性.也有 ...