[转]几种常见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 语句 分页查询是最常用的场景之一,但也通常 ...
随机推荐
- JDK环境变量的配置方法
1.打开我的电脑--属性--高级--环境变量 2.新建系统变量JAVA_HOME 变量名:JAVA_HOME 变量值:jdk的目录,比如d:/java 3. 选择“系统变量”中变量名为“Path”的环 ...
- Spring基于注解及SpringMVC
1.使用注解 (1)组件扫描 指定一个包路径,Spring会自动扫描该包 及其子包所有组件类,当发现组件类定义前有 特定的注解标记时,就将该组件纳入到Spring 容器.等价于原有XML配置中的< ...
- android: 从相册中选择照片
虽然调用摄像头拍照既方便又快捷,但并不是每一次我们都需要去当场拍一张照片的. 因为每个人的手机相册里应该都会存有许许多多张照片,直接从相册里选取一张现有的照 片会比打开相机拍一张照片更加常用.一个优秀 ...
- RFID Exploration and Spoofer a bipolar transistor, a pair of FETs, and a rectifying full-bridge followed by a loading FET
RFID Exploration Louis Yi, Mary Ruthven, Kevin O'Toole, & Jay Patterson What did you do? We made ...
- 极简MVC的实现
我们来打造一个简单的专用于json调用的mvc实现,最终会将如下的C#代码暴露给js调用(代码在最后面有下载): public class UserController { public static ...
- JXLS 双循环模板
商户名称 门店代码 时间 金额 <jx:forEach items="${resultList}" var="l"> ${l.name} ...
- Android防止按钮连续点击
为了防止用户或者测试MM疯狂的点击某个button,写个方法防止按钮连续点击. public class Utils { private static long lastClickTime; publ ...
- Windows下msysGit使用及相关配置
Windows下msysGit使用 目前我们git通过ssh进行通信,所以需要你也安装ssh以及将ssh key发给我,省得每次都需要输入用户名和密码 1.创建工程目录 windows下进入msysG ...
- 【译】在 Chrome 开发者工具中调试 node.js
原文链接 : Debugging Node.js in Chrome DevTools 原文作者 : MATT DESLAURIERS 译文出自 : 掘金翻译计划 译文链接 : https://git ...
- 云服务器上安装配置Filezilla Server的坑!
1.Filezilla被动模式配置如下,需要使用比较大号的端口,用1024以内的不行! 2.相应的,IP筛选器放开TCP-50020端口.不是UDP! 3.可以正常访问了.GOOD! 4.注意,服务器 ...