[转]几种常见SQL分页方式
创建环境:
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分页方式的更多相关文章
- 几种常见SQL分页方式效率比较(转)
http://www.cnblogs.com/iamowen/archive/2011/11/03/2235068.html 分页很重要,面试会遇到.不妨再回顾总结一下. 1.创建测试环境,(插入10 ...
- 几种常见SQL分页方式效率比较
分页很重要,面试会遇到.不妨再回顾总结一下: 一:创建测试环境,(插入100万条数据大概耗时5分钟). create database DBTestuse DBTest 二:--创建测试表 creat ...
- 常见SQL分页方式效率比较
结一下. 1.创建测试环境,(插入100万条数据大概耗时5分钟). ,) ) )) ),end 2.几种典型的分页sql,下面例子是每页50条,198*50=9900,取第199页数据. id id ...
- Spring RestTemplate中几种常见的请求方式GET请求 POST请求 PUT请求 DELETE请求
Spring RestTemplate中几种常见的请求方式 原文地址: https://blog.csdn.net/u012702547/article/details/77917939 版权声明 ...
- Spring RestTemplate中几种常见的请求方式
https://github.com/lenve/SimpleSpringCloud/tree/master/RestTemplate在Spring Cloud中服务的发现与消费一文中,当我们从服务消 ...
- Java几种常见的编码方式
几种常见的编码格式 为什么要编码 不知道大家有没有想过一个问题,那就是为什么要编码?我们能不能不编码?要回答这个问题必须要回到计算机是如何表示我们人类能够理解的符号的,这些符号也就是我们人类使用的语言 ...
- 目前常见的三种SQL分页方式:
--top not in方式 select top 条数 * from tablename where Id not in (select top 条数*页数 Id from tablename) - ...
- 8种常见SQL错误用法,你中招了吗?
作者:db匠 来源:https://yq.aliyun.com/articles/72501 1.LIMIT 语句 分页查询是最常用的场景之一,但也通常也是最容易出问题的地方.比如对于下面简单的语句, ...
- 8 种常见 SQL 错误用法
点击上方"开源Linux",选择"设为星标"回复"学习"获取独家整理的学习资料! 1.LIMIT 语句 分页查询是最常用的场景之一,但也通常 ...
随机推荐
- TF Boys (TensorFlow Boys ) 养成记(三)
上次说到了 TensorFlow 从文件读取数据,这次我们来谈一谈变量共享的问题. 为什么要共享变量?我举个简单的例子:例如,当我们研究生成对抗网络GAN的时候,判别器的任务是,如果接收到的是生成器生 ...
- javascript设计模式与开发实践阅读笔记(7)——迭代器模式
迭代器模式:指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. 迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺 ...
- .svn批量删除
c.bat @echo on @rem 删除SVN版本控制目录 @rem for /r . %%a in (.) do @if exist "%%a\.svn" @echo &qu ...
- Android 中的AIDL,Parcelable和远程服务
Android 中的AIDL,Parcelable和远程服务 早期在学习期间便接触到AIDL,当时对此的运用也是一撇而过.只到近日在项目中接触到AIDL,才开始仔细深入.AIDL的作用 ...
- 浏览器 CSS Hack 收集
所谓的Hack就是只有特定浏览器才能识别这段hack代码.Hack 不是什么好东西,除非没有办法,我们尽量还是不要用着玩意. 下面是各个浏览器的CSS Hack 列表. Firefox 浏览器 @-m ...
- AtomicInteger简介
这个类真的非常实用,更重要的是 它确实非常简单: 附上自己的代码,可以自己试试: AtomicInteger,一个提供原子操作的Integer的类.在Java语言中,++i和i++操作并不是线程安全的 ...
- 直接使用提交过来的类来更新字段EntityState.Modified并过滤null值的方法
public T Update<T>(T entity) where T : ModelBase { var set = this.Set<T>(); set.Attach(e ...
- 编译fresco源码
同步发表于http://avenwu.net/fresco/2015/05/07/build_fresco_sample fresco出来已经有一阵子了,曾经尝试过一次clone源码编译,主要是看其自 ...
- OAuth2.0和SSO授权
一.OAuth2.0授权协议 一种安全的登陆协议,用户提交的账户密码不提交到本APP,而是提交到授权服务器,待服务器确认后,返回本APP一个访问令牌,本APP即可用该访问令牌访问资源服务器的资源.由于 ...
- Microsoft.CSharp.CSharpCodeProvider
Microsoft.CSharp.CSharpCodeProvider MSDN 提供对 C# 代码生成器和代码编译器的实例的访问.类提供可用来检索 C# ICodeGenerator 和 ICode ...