2008年 最新海量数据分页
看了很多海量数据分页,大都都是单表的,而且当数据增大时效率下降但是排序的列不能有重复值,而在sql 2005 里通过 OVER子句可以解决,不过它也只是在后台把查询结果加一列,然后所有数据查一遍,每条记录插入序号,当有上千万数据时效率也是有点低的。
所以我归纳了下,如果排序的列有重复,就用sql2005 的存储过程,否则用我写的存储过程
sql 2005的存储过程:
create PROCEDURE [dbo].[SP_Common_PageChange]
@sql nvarchar(4000), --sql字符串
@OrderString nvarchar(100),
@PageIndex int,
@PageSize int,
@RecordCount int OUT,
@PageCount int OUT
AS
/*计算页面数据*/
Declare @PageIndex1 int
declare @sqlRecordCount nvarchar(4000)
Set @PageIndex1=@PageIndex+1;
set @sqlRecordCount ='select @RecordCount=count(*) from ('+@sql+') mxf'
/*获取记录数*/
EXEC sp_executesql @sqlRecordCount,N'@RecordCount int OUTPUT',@RecordCount OUTPUT--计算总页数
SET @PageCount = CEILING(@RecordCount * 1.0 / @PageSize)
SET @sql='('+@sql+') h'
/* 基于SQL SERVER 2005 */
SET @sql=N'select SerialNumber,* from (select *,row_number() over (order by '+@OrderString+')'
+'as serialnumber from '+@sql+') as T where T.SerialNumber > ( '+convert(nvarchar(100),@PageIndex)+' * '+ convert(nvarchar(100),@PageSize)+' ) and'
+' T.SerialNumber <= ( '+convert(nvarchar(100),@PageIndex1)+' * '+convert(nvarchar(100),@PageSize)+' )'
EXEC (@sql)
本人写的存储过程:
请查看 http://new.qzone.qq.com/34065028
[解决办法]
MARK.
[解决办法]
不过怎么说 取900到1000条数据 始终是要取前1000条的
[解决办法]
关注,学习!
[解决办法]
mar
[解决办法]
学习
[解决办法]
海量数据的分页始终都是一个难题。
[解决办法]
晕,我写的存储过程 可以不用
[解决办法]
[u][/u]
--------------排序-----------------0是降序,1未升序
set @Total=0
set @strOrderIn = ''
if @OrderType !=0
begin
set @strOrder='order by ' + @OrderField + ' asc '
end
else
begin
set @strOrder='order by '+ @OrderField + ' desc'
end
if RTRIM(LTRIM(@OrderValue)) = '' --传统分页
begin
-- -- 去掉前面的表
-- declare @tmpOrderField varchar(255)
-- set @tmpOrderField = @OrderField
-- set @tmpOrderField = REVERSE(@tmpOrderField);
-- set @tmpOrderField = SUBSTRING(@tmpOrderField,0,CHARINDEX('.',@tmpOrderField))
-- set @tmpOrderField = REVERSE(@tmpOrderField);
if @OrderType !=0
begin
set @strtemp= '>(select max(' + ' ' +@OrderField+ ') from (select top '
+str((@PageIndex-1)*@PageSize) + ' '+@OrderField +' from '+@tbNameS
+ @strWhereSql+ ' '+ @strOrder +') as tb)'
end
else
begin
set @strtemp= '<(select min('+ ' ' +@OrderField+ ') from (select top '
+str((@PageIndex-1)*@PageSize) + ' '+@OrderField +' from '+@tbNameS
+ @strWhereSql+ ' '+ @strOrder +') as tb)'
end
end
else
begin -- 根据 提供的比较值
declare @oper char(3)
set @oper = ''
if @PageDirection = 1
begin
if @OrderType != 0 -- desc 降序
begin
set @oper = ' > '
end
else
set @oper = ' < '
end
else
begin
if @OrderType !=0 -- desc 降序
begin
set @oper = ' < '
set @strOrderin = 'order by ' + @OrderField + ' desc '
end
else
begin
set @oper = ' > '
set @strOrderin = 'order by ' + @OrderField + ' asc '
end
end;
if @OrderFieldType = 'S'
begin
set @strtemp= @oper + +''''+ @OrderValue +'''';
end
else
set @strtemp= @oper + @OrderValue--cast(@OrderValue as int);
end
--------------分页为第一页------------
if @PageIndex =1 or @PageIndex =0
begin
set @PageIndex =1
set @strSql = 'Select top ' +str(@PageSize)+ ' ' + @tbFields + ' from '+ @tbNameS + @strWhereSql+ ' ' + @strOrder
end
else if @PageIndex = -1 --最后一页
begin
if @OrderType !=0
begin
set @strOrderIn='order by ' + @OrderField + ' desc '
end
else
begin
set @strOrderIn='order by '+ @OrderField + ' asc'
end
set @strSql = 'Select top ' +str(@PageSize)+ ' ' + @tbFields + ' from '+ @tbNameS + @strWhereSql + ' ' + @strOrderIn
set @strSql = 'Select * from (' + @strSql + ' ) t '+ @strOrder;
end
else
begin
declare @temp varchar(200)
set @temp = ''
if RTRIM(LTRIM(@strWhere)) != ''
set @temp = ' and ' + @strWhere
if if RTRIM(LTRIM(@OrderValue)) = ''
set @strSql = 'Select top ' +str(@PageSize) + ' ' + @tbFields
+' from ' + @tbNameS + ' where '+@OrderField +' '
+ @strtemp + ' ' + @temp + @strOrder
else
begin
set @strSql = 'Select top ' +str(@PageSize) + ' ' + @tbFields
+' from ' + @tbNameS + ' where '+@OrderField +' '
+ @strtemp + ' ' + @temp + @strOrderIn
set @strSql = 'select * from(' + @strSql + ') tb ' + @strOrder
end
end
exec sp_executesql @strSqlCount,N'@TotalCout int output',@Total output
exec(@strSql)
[解决办法]
@OrderValue varchar(20) = '', --排序字段上一次页最大或最小值
当 @OrderValue 不为空时,查询900到1000的数据 不用查询前900条,直接根据这个@OrderValue值就可以了。
[解决办法]
我个人不喜欢所谓“通用”的分页存储过程
分页需要通盘考虑取出来的字段的类型,排序字段是否可以保证唯一。你做的优化前提之一就是要有唯一的排序字段,结合业务逻辑考虑,这个排序字段可能包含多个,那你的@orderValue参数该怎么传?
我认为分页存储过程只应该有一个通用的写法.
有唯一排序字段,该怎么写/没有唯一排序字段,该怎么写. 类似这样
[解决办法]
再也不要写什么千万级的分页存储过程.
客户需要的内容 最好确定在一页 或者 几页.
几千万条数据分页展现给用户,你想他在里面淘金啊.
[解决办法]