/* 名称:spAll_ReturnRows 输入: 输出: 调用: EXEC spAll_ReturnRows 'select * FROM 表名', 页号, 返回记录数, '主键', '排序字段' spAll_ReturnRows 'select * FROM all_Categories',2,10,'[ID]','[ID]' 说明:[百万级]通用存储过程.分页存储过程..返回指定返回条数、指定页数的记录 作者:Dili J.F. Senders 邮件:diliatwellknow.net 更新:20040610 版权:转述时请注明来源:用思维创造未来的Wellknow.net */ create PROCEDURE dbo.spAll_ReturnRows ( @SQL nVARCHAR(4000), @Page int, @RecsPerPage int, @ID VARCHAR(255), @Sort VARCHAR(255) ) AS DECLARE @Str nVARCHAR(4000) SET @Str='select TOP '+cast(@RecsPerPage AS VARCHAR(20))+' * FROM ('+@SQL+') T where T.'+@ID+' NOT IN (select TOP '+cast((@RecsPerPage*(@Page-1)) AS VARCHAR(20))+' '+@ID+' FROM ('+@SQL+') T9 ORDER BY '+@Sort+') ORDER BY '+@Sort PRINT @Str EXEC sp_ExecuteSql @Str GO /* 名称:spAll_deleteNoneUnique 输入:要查询的表名和字段列表 输出: 调用: 说明:实现千万级数据的分页显示!--可以在5秒内获取1448万条记录里的第1200页的100条记录,雄不? 作者:铁拳版权:转述时请注明来源:用思维创造未来的Wellknow.net */ create PROCEDURE GetRecordFromPage @tblName varchar(255), -- 表名 @fldName varchar(255), -- 字段名 @PageSize int = 10, -- 页尺寸 @PageIndex int = 1, -- 页码 @IsCount bit = 0, -- 返回记录总数, 非 0 值则返回 @OrderType bit = 0, -- 设置排序类型, 非 0 值则降序 @strwhere varchar(1000) = '' -- 查询条件 (注意: 不要加 where) AS declare @strSQL varchar(6000) -- 主语句 declare @strTmp varchar(100) -- 临时变量 declare @strOrder varchar(400) -- 排序类型 if @OrderType != 0 begin set @strTmp = "<(select min" set @strOrder = " order by [" + @fldName +"] desc" end else begin set @strTmp = ">(select max" set @strOrder = " order by [" + @fldName +"] asc" end set @strSQL = "select top " + str(@PageSize) + " * 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) + " * from [" + @tblName + "] where [" + @fldName + "]" + @strTmp + "([" + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " [" + @fldName + "] from [" + @tblName + "] where " + @strwhere + " " + @strOrder + ") as tblTmp) and " + @strwhere + " " + @strOrder if @PageIndex = 1 begin set @strTmp = "" if @strwhere != '' set @strTmp = " where " + @strwhere set @strSQL = "select top " + str(@PageSize) + " * from [" + @tblName + "]" + @strTmp + " " + @strOrder end if @IsCount != 0 set @strSQL = "select count(*) as Total from [" + @tblName + "]" exec (@strSQL) GO 个人研究百万级数据提出问题总结如下: 1.除了提高硬件方面 2.采取折中方法,一次提出几百万数据也没有什么实在意义 不过存储过程写的还是很精妙。 p=pagesize,n为返回页数,SQL="select * from product where id<200000" 1.(select * from product where id<200000) as t 2.(select top p*(n-1) t.id from t order by id asc) as t1 3.select top p * from t where id not in t1 order by id asc SQL: select top p * from (select * from product where id<200000) t where t.id not in (select top p*(n-1) id from t order by id asc) order by id asc [注:子查询里面别名t 其实并不存在,应该用1.重新代替] SQL存储过程: SET @str='select top'+cast(@p as varchar(20))+' * from ('+@SQL+') t where t.'+@ID+' not in (select top '+cast((@p*(@n-1)) as varchar(20))+' '+@ID+' from ('+SQL+') order by '+@Sort+') order by '+@Sort PRINT @str 百万级数据测试结果如下: ////////////////////////////// ///result:100W数据 /// ///条件:VirtualItemCount=200000 ///->转1页 33.924982085712 milliseconds,33.3696042374101 milliseconds,31.1483722093171 milliseconds ///->转1000页 247.380882207096 milliseconds,190.643224208663 milliseconds,240.085262233049 milliseconds ///->转10000页 2393.90201827327 milliseconds,1903.65535284512 milliseconds,1839.06278591273 milliseconds /// ///条件:VirtualItemCount=all ///->1 10.2540965402027 milliseconds,7.47608983823363 milliseconds,15.5991892824367 milliseconds ///->1000 273.380555349912 milliseconds,190.414982909839 milliseconds,217.308345055028 milliseconds ///->10000 1845.92064075183 milliseconds,1951.84974626663 milliseconds,1904.51831168487 milliseconds /// ///2s处理百万数据 ////////////////////////////// |