- 浏览: 787022 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (573)
- Java基础 (76)
- C++基础 (5)
- hibernate (5)
- struts (4)
- spring (1)
- webservice (7)
- AjaX基础 (0)
- JS脚本 (53)
- 正则表达式 (5)
- html脚本 (30)
- 数据库基础 (54)
- 工作相关 (49)
- 其他 (30)
- Linux (9)
- web服务器 (17)
- JSP (13)
- eclipse (6)
- 面试题相关 (20)
- XML (3)
- Apache common (2)
- 生活 (35)
- VMware (1)
- log4j (9)
- BeanUtils (2)
- 设计模式 (3)
- UML (1)
- UNIX (1)
- ibats (5)
- GT-Grid (17)
- ABAP学习 (17)
- ABAP (35)
- ABAP--ALV (11)
- ABAP--WEBDIMPRO (0)
- abap-sample (1)
- BEMS (2)
- flex (33)
- GIS技术 (3)
最新评论
公司一项目数据达到上百万,普通的分页方式满足不了要求,经常发生超时的错误,所以有必要对分页的方式来做下研究。
经过搜集和测试,当前网上的成熟的分页方式有以下几种方案:
分页存储过程1. 以下为引用的内容:
/*
说明:适合单表查询 cn-web.com提供
*/
CREATE PROCEDURE p_qcd_Pagination
@tblName varchar(255), -- 表名
@strGetFields varchar(1000) = '*', -- 需要返回的列
@fldName varchar(255)='', -- 排序的字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@doCount bit = 0, -- 返回记录总数, 非 0 值则返回
@OrderType bit = 0, -- 设置排序类型, 非 0 值则降序
@strWhere varchar(1500) = '' -- 查询条件 (注意: 不要加 where)
AS
declare @strSQL varchar(5000) -- 主语句
declare @strTmp varchar(110) -- 临时变量
declare @strOrder varchar(400) -- 排序类型
if @doCount != 0
begin
if @strWhere !=''
set @strSQL = 'select count(*) as Total from ['+ @tblName +'] where '+ @strWhere
else
set @strSQL = 'select count(*) as Total from ['+ @tblName +']'
end
--以上代码的意思是如果@doCount传递过来的不是0,就执行总数统计。以下的所有代码都
--是@doCount为0的情况
else
begin
if @OrderType != 0
begin
set @strTmp = '<(select min'
set @strOrder = ' order by ['+ @fldName +'] desc'
--如果@OrderType不是0,就执行降序,这句很重要!
end
else
begin
set @strTmp = '>(select max'
set @strOrder = ' order by ['+ @fldName +'] asc'
end
if @PageIndex = 1
begin
if @strWhere != ''
set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from ['+ @tblName +'] where ' + @strWhere + ' ' + @strOrder
else
set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from ['+ @tblName +'] '+ @strOrder
--如果是第一页就执行以上代码,这样会加快执行速度
end
else
begin
--以下代码赋予了@strSQL以真正执行的SQL代码
set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from [' + @tblName +'] where [' + @fldName + ']' + @strTmp + '(['+ @fldName + '])
from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['+ @fldName + '] from ['+ @tblName +']' + @strOrder + ') as tblTmp)'+ @strOrder
if @strWhere != ''
set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from ['+ @tblName +'] where [' + @fldName + ']' + @strTmp + '(['+ @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['+ @fldName + ']
from ['+ @tblName +'] where ' + @strWhere + ' ' + @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder
end
end
exec ( @strSQL)
GO
此方案只适合单表,中小数据查询,当条件出现in(1,2,3,4,5……)时,则速度明显下降。
分页存储过程2
以下为引用的内容:
create PROCEDURE p_qcd_PaginationDichotomy
(
@tblName nvarchar(200), ----要显示的表或多个表的连接
@fldName nvarchar(500) = '*', ----要显示的字段列表
@pageSize int = 10, ----每页显示的记录个数
@page int = 1, ----要显示那一页的记录
@fldSort nvarchar(200) = null, ----排序字段列表或条件
@Sort bit = 0, ----排序方法,0为升序,1为降序(如果是多字段排列Sort指代最后一个排序字段的排列顺序(最后一个排序字段不加排序标记)--程序传参如:' SortA Asc,SortB Desc,SortC ')
@strCondition nvarchar(1000) = null, ----查询条件,不需where
@ID nvarchar(150), ----主表的主键
@Dist bit = 0, ----是否添加查询字段的 DISTINCT 默认0不添加/1添加
@pageCount int = 1 output, ----查询结果分页后的总页数
@Counts int = 1 output ----查询到的记录数
)
AS
SET NOCOUNT ON
Declare @sqlTmp nvarchar(1000) ----存放动态生成的SQL语句
Declare @strTmp nvarchar(1000) ----存放取得查询结果总数的查询语句
Declare @strID nvarchar(1000) ----存放取得查询开头或结尾ID的查询语句
Declare @strSortType nvarchar(10) ----数据排序规则A
Declare @strFSortType nvarchar(10) ----数据排序规则B
Declare @SqlSelect nvarchar(50) ----对含有DISTINCT的查询进行SQL构造
Declare @SqlCounts nvarchar(50) ----对含有DISTINCT的总数查询进行SQL构造
declare @timediff datetime --耗时测试时间差
select @timediff=getdate()
if @Dist = 0
begin
set @SqlSelect = 'select '
set @SqlCounts = 'Count(*)'
end
else
begin
set @SqlSelect = 'select distinct '
set @SqlCounts = 'Count(DISTINCT '+@ID+')'
end
if @Sort=0
begin
set @strFSortType=' ASC '
set @strSortType=' DESC '
end
else
begin
set @strFSortType=' DESC '
set @strSortType=' ASC '
end
--------生成查询语句cn-web.com提供--------
--此处@strTmp为取得查询结果数量的语句
if @strCondition is null or @strCondition='' --没有设置显示条件
begin
set @sqlTmp = @fldName + ' From ' + @tblName
set @strTmp = @SqlSelect+' @Counts='+@SqlCounts+' FROM '+@tblName
set @strID = ' From ' + @tblName
end
else
begin
set @sqlTmp = + @fldName + 'From ' + @tblName + ' where (1>0) ' + @strCondition
set @strTmp = @SqlSelect+' @Counts='+@SqlCounts+' FROM '+@tblName + ' where (1>0) ' + @strCondition
set @strID = ' From ' + @tblName + ' where (1>0) ' + @strCondition
end
----取得查询结果总数量-----
exec sp_executesql @strTmp,N'@Counts int out ',@Counts out
declare @tmpCounts int
if @Counts = 0
set @tmpCounts = 1
else
set @tmpCounts = @Counts
--取得分页总数
set @pageCount=(@tmpCounts+@pageSize-1)/@pageSize
/**//**//**//**当前页大于总页数 取最后一页**/
if @page>@pageCount
set @page=@pageCount
--/*-----数据分页2分处理-------*/
declare @pageIndex int --总数/页大小
declare @lastcount int --总数%页大小
set @pageIndex = @tmpCounts/@pageSize
set @lastcount = @tmpCounts%@pageSize
if @lastcount > 0
set @pageIndex = @pageIndex + 1
else
set @lastcount = @pagesize
--//***显示分页
if @strCondition is null or @strCondition='' --没有设置显示条件
begin
if @pageIndex<2 or @page<=@pageIndex / 2 + @pageIndex % 2 --前半部分数据处理
begin
if @page=1
set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' order by '+ @fldSort +' '+ @strFSortType
else
begin
if @Sort=1
begin
set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' <(select min('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName
+' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)'
+' order by '+ @fldSort +' '+ @strFSortType
end
else
begin
set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' >(select max('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName
+' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)'
+' order by '+ @fldSort +' '+ @strFSortType
end
end
end
else
begin
set @page = @pageIndex-@page+1 --后半部分数据处理
if @page <= 1 --最后一页数据显示
set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@lastcount as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType
else
if @Sort=1
begin
set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' >(select max('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName
+' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)'
+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType
end
else
begin
set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' <(select min('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName
+' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)'
+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType
end
end
end =@pageIndex / 2 + @pageIndex % 2 --前半部分数据处理
begin
if @page=1
set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where 1=1 ' + @strCondition + ' order by '+ @fldSort +' '+ @strFSortType
else if(@Sort=1)
begin
set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' <(select min('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName
+' where (1=1) ' + @strCondition +' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)'
+' '+ @strCondition +' order by '+ @fldSort +' '+ @strFSortType
end
else
begin
set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' >(select max('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName
+' where (1=1) ' + @strCondition +' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)'
+' '+ @strCondition +' order by '+ @fldSort +' '+ @strFSortType
end
end
else
begin
set @page = @pageIndex-@page+1 --后半部分数据处理
if @page <= 1 --最后一页数据显示
set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@lastcount as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where (1=1) '+ @strCondition +' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType
else if(@Sort=1)
set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' >(select max('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName
+' where (1=1) '+ @strCondition +' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)'
+' '+ @strCondition+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType
else
set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' <(select min('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName
+' where (1=1) '+ @strCondition +' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)'
+' '+ @strCondition+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType
end
end
else --有查询条件
begin
if @pageIndex<2 or @page<
------返回查询结果-----
--select @pageCount ,@Counts
--select @pageCount
exec sp_executesql @strTmp
select datediff(ms,@timediff,getdate()) as 耗时
--print @strTmp
SET NOCOUNT OFF
GO
此分页俗称二分法,执行效率超快,数据量达到百万后效率也没有明显下降,缺点同上,当条件出现in(1,2,3,4,5……)时,则速度明显下降。
分页存储过程3
以下为引用的内容:
CREATE procedure p_qcd_Paginationcursor
@sql nvarchar(4000), --要执行的sql语句
@currentpage int=1, --要显示的页码
@pagesize int=10, --每页的大小
@pagecount int=0 out, --总页数
@recordCount int=0 out--总记录数
as
set nocount on
declare @cursor int --cursor 是游标的id
declare @timediff datetime --耗时测试时间差 cn-web.com提供
select @timediff=getdate()
exec sp_cursoropen @cursor output,@sql,@scrollopt=1,@ccopt=1,@rowcount=@pagecount output
select @recordCount=@pagecount
select @pagecount=ceiling(1.0*@pagecount/@pagesize) ,@currentpage=(@currentpage-1)*@pagesize+1
select @pagecount,@currentpage
exec sp_cursorfetch @cursor ,16,@currentpage,@pagesize
exec sp_cursorclose @cursor
select datediff(ms,@timediff,getdate()) as 耗时
GO
此方案所说是微软没有公开的游标分页,刚开始怀疑游标分页肯定浪费性能,不过经过详细测试后,发现微软就是微软,不管如何测试,不管条件如何复杂,数据量再大,性能一直保持最强劲。
总结:在没有in(1,2,3,4,5……)之类的条件的查询时,三种方案的性能:方案3=方案2>方案1。当存在复杂条件时,方案3>方案2=方案1。
经过搜集和测试,当前网上的成熟的分页方式有以下几种方案:
分页存储过程1. 以下为引用的内容:
/*
说明:适合单表查询 cn-web.com提供
*/
CREATE PROCEDURE p_qcd_Pagination
@tblName varchar(255), -- 表名
@strGetFields varchar(1000) = '*', -- 需要返回的列
@fldName varchar(255)='', -- 排序的字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@doCount bit = 0, -- 返回记录总数, 非 0 值则返回
@OrderType bit = 0, -- 设置排序类型, 非 0 值则降序
@strWhere varchar(1500) = '' -- 查询条件 (注意: 不要加 where)
AS
declare @strSQL varchar(5000) -- 主语句
declare @strTmp varchar(110) -- 临时变量
declare @strOrder varchar(400) -- 排序类型
if @doCount != 0
begin
if @strWhere !=''
set @strSQL = 'select count(*) as Total from ['+ @tblName +'] where '+ @strWhere
else
set @strSQL = 'select count(*) as Total from ['+ @tblName +']'
end
--以上代码的意思是如果@doCount传递过来的不是0,就执行总数统计。以下的所有代码都
--是@doCount为0的情况
else
begin
if @OrderType != 0
begin
set @strTmp = '<(select min'
set @strOrder = ' order by ['+ @fldName +'] desc'
--如果@OrderType不是0,就执行降序,这句很重要!
end
else
begin
set @strTmp = '>(select max'
set @strOrder = ' order by ['+ @fldName +'] asc'
end
if @PageIndex = 1
begin
if @strWhere != ''
set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from ['+ @tblName +'] where ' + @strWhere + ' ' + @strOrder
else
set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from ['+ @tblName +'] '+ @strOrder
--如果是第一页就执行以上代码,这样会加快执行速度
end
else
begin
--以下代码赋予了@strSQL以真正执行的SQL代码
set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from [' + @tblName +'] where [' + @fldName + ']' + @strTmp + '(['+ @fldName + '])
from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['+ @fldName + '] from ['+ @tblName +']' + @strOrder + ') as tblTmp)'+ @strOrder
if @strWhere != ''
set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from ['+ @tblName +'] where [' + @fldName + ']' + @strTmp + '(['+ @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['+ @fldName + ']
from ['+ @tblName +'] where ' + @strWhere + ' ' + @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder
end
end
exec ( @strSQL)
GO
此方案只适合单表,中小数据查询,当条件出现in(1,2,3,4,5……)时,则速度明显下降。
分页存储过程2
以下为引用的内容:
create PROCEDURE p_qcd_PaginationDichotomy
(
@tblName nvarchar(200), ----要显示的表或多个表的连接
@fldName nvarchar(500) = '*', ----要显示的字段列表
@pageSize int = 10, ----每页显示的记录个数
@page int = 1, ----要显示那一页的记录
@fldSort nvarchar(200) = null, ----排序字段列表或条件
@Sort bit = 0, ----排序方法,0为升序,1为降序(如果是多字段排列Sort指代最后一个排序字段的排列顺序(最后一个排序字段不加排序标记)--程序传参如:' SortA Asc,SortB Desc,SortC ')
@strCondition nvarchar(1000) = null, ----查询条件,不需where
@ID nvarchar(150), ----主表的主键
@Dist bit = 0, ----是否添加查询字段的 DISTINCT 默认0不添加/1添加
@pageCount int = 1 output, ----查询结果分页后的总页数
@Counts int = 1 output ----查询到的记录数
)
AS
SET NOCOUNT ON
Declare @sqlTmp nvarchar(1000) ----存放动态生成的SQL语句
Declare @strTmp nvarchar(1000) ----存放取得查询结果总数的查询语句
Declare @strID nvarchar(1000) ----存放取得查询开头或结尾ID的查询语句
Declare @strSortType nvarchar(10) ----数据排序规则A
Declare @strFSortType nvarchar(10) ----数据排序规则B
Declare @SqlSelect nvarchar(50) ----对含有DISTINCT的查询进行SQL构造
Declare @SqlCounts nvarchar(50) ----对含有DISTINCT的总数查询进行SQL构造
declare @timediff datetime --耗时测试时间差
select @timediff=getdate()
if @Dist = 0
begin
set @SqlSelect = 'select '
set @SqlCounts = 'Count(*)'
end
else
begin
set @SqlSelect = 'select distinct '
set @SqlCounts = 'Count(DISTINCT '+@ID+')'
end
if @Sort=0
begin
set @strFSortType=' ASC '
set @strSortType=' DESC '
end
else
begin
set @strFSortType=' DESC '
set @strSortType=' ASC '
end
--------生成查询语句cn-web.com提供--------
--此处@strTmp为取得查询结果数量的语句
if @strCondition is null or @strCondition='' --没有设置显示条件
begin
set @sqlTmp = @fldName + ' From ' + @tblName
set @strTmp = @SqlSelect+' @Counts='+@SqlCounts+' FROM '+@tblName
set @strID = ' From ' + @tblName
end
else
begin
set @sqlTmp = + @fldName + 'From ' + @tblName + ' where (1>0) ' + @strCondition
set @strTmp = @SqlSelect+' @Counts='+@SqlCounts+' FROM '+@tblName + ' where (1>0) ' + @strCondition
set @strID = ' From ' + @tblName + ' where (1>0) ' + @strCondition
end
----取得查询结果总数量-----
exec sp_executesql @strTmp,N'@Counts int out ',@Counts out
declare @tmpCounts int
if @Counts = 0
set @tmpCounts = 1
else
set @tmpCounts = @Counts
--取得分页总数
set @pageCount=(@tmpCounts+@pageSize-1)/@pageSize
/**//**//**//**当前页大于总页数 取最后一页**/
if @page>@pageCount
set @page=@pageCount
--/*-----数据分页2分处理-------*/
declare @pageIndex int --总数/页大小
declare @lastcount int --总数%页大小
set @pageIndex = @tmpCounts/@pageSize
set @lastcount = @tmpCounts%@pageSize
if @lastcount > 0
set @pageIndex = @pageIndex + 1
else
set @lastcount = @pagesize
--//***显示分页
if @strCondition is null or @strCondition='' --没有设置显示条件
begin
if @pageIndex<2 or @page<=@pageIndex / 2 + @pageIndex % 2 --前半部分数据处理
begin
if @page=1
set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' order by '+ @fldSort +' '+ @strFSortType
else
begin
if @Sort=1
begin
set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' <(select min('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName
+' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)'
+' order by '+ @fldSort +' '+ @strFSortType
end
else
begin
set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' >(select max('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName
+' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)'
+' order by '+ @fldSort +' '+ @strFSortType
end
end
end
else
begin
set @page = @pageIndex-@page+1 --后半部分数据处理
if @page <= 1 --最后一页数据显示
set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@lastcount as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType
else
if @Sort=1
begin
set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' >(select max('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName
+' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)'
+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType
end
else
begin
set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' <(select min('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName
+' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)'
+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType
end
end
end =@pageIndex / 2 + @pageIndex % 2 --前半部分数据处理
begin
if @page=1
set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where 1=1 ' + @strCondition + ' order by '+ @fldSort +' '+ @strFSortType
else if(@Sort=1)
begin
set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' <(select min('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName
+' where (1=1) ' + @strCondition +' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)'
+' '+ @strCondition +' order by '+ @fldSort +' '+ @strFSortType
end
else
begin
set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' >(select max('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName
+' where (1=1) ' + @strCondition +' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)'
+' '+ @strCondition +' order by '+ @fldSort +' '+ @strFSortType
end
end
else
begin
set @page = @pageIndex-@page+1 --后半部分数据处理
if @page <= 1 --最后一页数据显示
set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@lastcount as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where (1=1) '+ @strCondition +' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType
else if(@Sort=1)
set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' >(select max('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName
+' where (1=1) '+ @strCondition +' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)'
+' '+ @strCondition+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType
else
set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName
+' where '+@ID+' <(select min('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName
+' where (1=1) '+ @strCondition +' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)'
+' '+ @strCondition+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType
end
end
else --有查询条件
begin
if @pageIndex<2 or @page<
------返回查询结果-----
--select @pageCount ,@Counts
--select @pageCount
exec sp_executesql @strTmp
select datediff(ms,@timediff,getdate()) as 耗时
--print @strTmp
SET NOCOUNT OFF
GO
此分页俗称二分法,执行效率超快,数据量达到百万后效率也没有明显下降,缺点同上,当条件出现in(1,2,3,4,5……)时,则速度明显下降。
分页存储过程3
以下为引用的内容:
CREATE procedure p_qcd_Paginationcursor
@sql nvarchar(4000), --要执行的sql语句
@currentpage int=1, --要显示的页码
@pagesize int=10, --每页的大小
@pagecount int=0 out, --总页数
@recordCount int=0 out--总记录数
as
set nocount on
declare @cursor int --cursor 是游标的id
declare @timediff datetime --耗时测试时间差 cn-web.com提供
select @timediff=getdate()
exec sp_cursoropen @cursor output,@sql,@scrollopt=1,@ccopt=1,@rowcount=@pagecount output
select @recordCount=@pagecount
select @pagecount=ceiling(1.0*@pagecount/@pagesize) ,@currentpage=(@currentpage-1)*@pagesize+1
select @pagecount,@currentpage
exec sp_cursorfetch @cursor ,16,@currentpage,@pagesize
exec sp_cursorclose @cursor
select datediff(ms,@timediff,getdate()) as 耗时
GO
此方案所说是微软没有公开的游标分页,刚开始怀疑游标分页肯定浪费性能,不过经过详细测试后,发现微软就是微软,不管如何测试,不管条件如何复杂,数据量再大,性能一直保持最强劲。
总结:在没有in(1,2,3,4,5……)之类的条件的查询时,三种方案的性能:方案3=方案2>方案1。当存在复杂条件时,方案3>方案2=方案1。
发表评论
-
oracle获取指定的日期、时间
2012-07-17 14:32 1075--本周 select trunc(sysdate, 'd ... -
Oracle 常用日期提取脚本汇总
2012-07-17 14:30 815Oracle 常用日期提取脚本汇总 1、本周第一天和最后一 ... -
Windows下安装PostgreSQL8.2图解
2010-08-20 13:16 1184Windows下安装PostgreSQL8.2图解 -
关于用户角色权限管理一点想法
2010-06-09 10:46 1090关键字: 权限 --------------------- ... -
sql语句解析顺序
2010-05-20 14:47 1355标准的 SQL 的解析顺序 ... -
postgreSql 利用触发器创建动态表
2010-05-20 14:43 1729在postgresql 中如果在程序运行中需要根据插入数据条件 ... -
使用反射实现ORM
2010-01-14 22:09 936首先Bean在符合JavaBean的要求,即有一个无参的构造方 ... -
模板设计模式_构建公共通用的Dao
2010-01-14 22:04 953核心代码: Connection的工具类:详见:JDBC数据 ... -
使用构造函数创建JavaScript对象
2010-01-14 21:31 948<!DOCTYPE html PUBLIC " ... -
数据库行转列
2010-01-14 21:09 811create table score ( s_id int ... -
SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
2010-01-14 20:56 911Insert是T-sql中常用语句,Insert INTO t ... -
mysql导入导出
2010-01-12 12:05 14641. 导出 view plaincopy to clip ... -
mysql导入与导出和删除多条数据数据
2010-01-12 11:57 2257数据导出: mysql> select * from ... -
MySQL索引分类和各自用途
2010-01-12 11:43 1488一、 MySQL: 索引以B树格 ... -
各种主流数据库的分页写法
2010-01-11 16:38 639------------------------------- ... -
MySQL中进行树状所有子节点的查询
2010-01-06 21:16 1229在Oracle 中我们知道有一个 Hierarchical Q ... -
MySQL中进行树状所有子节点的查询
2009-12-29 14:52 1003在Oracle 中我们知道有一个 Hierarchical Q ... -
超详细的SQL语句语法
2009-12-28 18:08 1021简单的Transact-SQL查询只包括选择列表、FROM子句 ... -
有关SQL模糊查询
2009-12-28 12:50 1197执行 数据库查询时,有 ... -
视图,存储过程,触发器的好处
2009-12-23 11:33 1066视图的优点: 提高数据安全性,可以不让用户看到表中的某个字 ...
相关推荐
本文将深入探讨SQL Server存储过程中的高级分页技术,特别是针对千万级别数据量的场景,通过分析提供的代码示例,提炼出核心知识点,帮助读者理解和掌握高效分页查询的实现方法。 ### 1. 使用临时表和ROWCOUNT实现...
通过研究这个项目,开发者可以学习到SSH框架的整合、Spring的bean管理和事务处理、Hibernate的数据库操作,以及SQLServer的分页查询技巧。同时,对于提高Web应用的用户体验,理解分页原理和实现方式也是必不可少的。
本资源提供了基于JSP(JavaServer Pages)和SQL Server数据库的分页实现源码,适合对这方面感兴趣或者正在开发类似功能的开发者参考。 JSP是一种服务器端脚本语言,用于创建动态Web页面。它结合了HTML、Java代码和...
【SQL Server 2000的Northwind...通过深入研究和实践Northwind数据库,不仅能够掌握SQL Server 2000的基本操作,还能进一步提升数据库设计、查询优化、安全管理等方面的能力,为后续的数据库管理工作打下坚实的基础。
在本例中,我们关注的是LINQ to SQL,这是一种特定的LINQ实现,它用于与关系数据库进行交互,如SQL Server 2005。在VS2008中,LINQ to SQL提供了直观的方式来映射数据库模式到.NET类,从而简化了数据访问。 分页是...
在ASP+SQL Server 2000网络书店系统中,SQL Server 2000主要负责存储书籍信息、用户信息、订单等数据,并处理来自ASP页面的数据库操作请求。 **系统功能模块** 1. **用户模块**:包括用户注册、登录、个人信息管理...
【个人博客系统(jsp+sqlserver2000)源代码】是一个专为初学者设计的项目,旨在帮助他们理解如何构建一个基于Web的博客平台。这个系统利用Java Server Pages (JSP)技术来处理前端展示和后端逻辑,同时借助SQL Server ...
- **数据展示与检索**:如何从SQL Server获取数据并展示在网页上,例如搜索功能、分页显示等。 - **事务处理**:涉及多表操作时,源代码可能会展示如何使用SQL Server的事务管理确保数据一致性。 通过深入研究这...
2. 数据展示与分页:通过GridView、Repeater等控件,演示如何从SQL Server 2005中检索并展示数据,同时实现数据的分页和排序。 3. 多层架构设计:模拟真实项目,展示业务逻辑层(Business Logic Layer, BLL)、数据...
本文将详细讨论“winform的分页控件,带数据分页”的实现方法、重要性以及相关的技术点。 首先,我们要明白“分页”是什么。在数据管理中,分页是一种将大量数据分割成多个较小部分(页)的策略,每一页可以独立...
建议下载并仔细研究该文件,以便更深入地理解JSP中数据分页的实现过程。 总的来说,数据分页显示是JSP和数据库操作中的一个重要环节,它涉及到数据库查询优化、服务器资源管理以及用户交互设计。通过合理的分页,...
在本文中,我们使用了ASP来实现分页技术,因为ASP具有易于编程,无需编译的特点,数据库使用的是Ms SQL server,因为MsSQL数据库和ASP同属MS的产品,开发时更加高效。本文中的ASP页面不仅实现了基本的分页显示技术,...
通过《SQL Server 2005数据库管理与应用高手修炼指南》的配套文件,读者可以找到实战练习和案例研究,加深对上述知识点的理解和应用。这些文件可能包括练习数据库、示例脚本、解决方案模板等,帮助读者在实践中提升...
2. **SQL Server 2005**:作为Microsoft的旗舰级关系型数据库管理系统,SQL Server 2005提供了强大的数据存储和处理能力。在本实例中,我们将学习如何设计数据库结构、创建表、设置关系以及执行SQL查询。 3. **...
文章通过一个教学评价系统的例子展示了如何使用ROW_NUMBER()结合通用表表达式(CTE)来实现高效的数据分页查询,这样只需要返回当前页的数据行,大大提高了查询效率。 文章还回顾了在SQL Server早期版本中获取排名...
通常,我们可以使用`OFFSET-FETCH`(SQL Server 2012及以上版本)或`ROW_NUMBER() OVER (ORDER BY ...)`子句来获取指定范围的数据。对于DBA(数据库管理员)来说,优化这些查询以减少I/O操作和提高查询速度至关重要...
数据分页查询控件在IT领域中是一种常见且重要的组件,尤其在开发数据库驱动的应用程序时,用于处理大量数据的展示。"数据分页查询控件(含源码与Demo).rar" 提供了实现这一功能的具体代码示例和演示项目,这对于...
【标题】"bbs.rar_bbs_bbs_sqlserver_java_java_BBS_simple_bbs_java_sqlserver"揭示了这个压缩包是一个关于论坛(BBS)开发的资源,主要涉及到的技术栈是Java编程语言和SQL Server数据库系统。这个简单的Java BBS...
在ASP(Active Server Pages)开发中,结合jQuery的AJAX(Asynchronous JavaScript and XML)功能,可以实现数据的动态加载和分页效果,提供更流畅的用户体验。本示例将详细解析如何使用jQuery AJAX实现ASP分页功能...
这可能涉及到SQL Server的`TOP`子句、`OFFSET/FETCH`或`LIMIT/OFFSET`(取决于数据库系统),以及如何动态调整查询条件来适应分页需求。同时,控件还需要处理页码导航、每页记录数的设置以及总页数的计算等功能。 ...