日期:2014-05-19  浏览次数:20521 次

关于高效分页
select   top   11   @id   =   ID   from   Table

  select   top   10   *   from   Table   where   ID   > =   @ID  

(公式:PageSize   *   (PageIndex   -   1)   +   1   =   11)


A   高效算法
这是一个非常追求效率的算法,依据MSSQL的特性,为简单分页的情况量身定做的。
第一个特性:select   top   11   @id   =   ID   from   Table
Top   和   给变量赋值都是很常用的方法,但是这种组合不太常见吧。这是我在一个偶然的情况下发现的,这么写有什么作用呢?先来看看@id会得到什么值。@id   得到的是最后一条记录的ID字段的值,前面的记录的值会被覆盖。
假设分页要求是:每页显示10条记录,按照ID字段升序显示。那么这时候   select   top   10   *   from   Table   where   ID   > =   @ID   得到的记录集就是第二页所需要的数据。第三页的数据只要把第一个语句   top   后面的   “11”改成“21”就可以了。公式:PageSize   *   (PageIndex   -   1)   +   1
要想使用这个特性必须满足几个条件:排序字段只能有一个,排序字段的值不能有太多重复的,有重复值会造成分页不准,甚至无法翻到下一页的情况。所以这个算法只适用于“简单分页”的情况。不过好在一个网站里面有很多情况都是“简单分页”的情况,随意这个算法还是有价值的。
Ps:这个特性好像只有MSSQL才有,SQLAnywhere是不容许这样写的,除非记录集只有一条记录,oracle   根本就没有top,其它的数据库没有研究过。
思路:先定位(数数),后取记录集(ID   > =   的方法)。
优点:第一个语句只取一个字段,即使是top   10000也可以把占用的资源降到最低。如果排序字段有索引的话效果更佳。


哪位能提供完整实例呀(结合AspNetPager控件的)。写了大半天写不出来。有点郁闷的。

------解决方案--------------------
CREATE PROCEDURE dbo.P_Pager
@strTable varchar(500), --表名
@strColumn varchar(50), --按该列来进行分页
@intColType int, --@strColumn列的类型,0-数字类型,1-字符类型,2-日期时间类型
@intOrder bit, --排序,0-顺序,1-倒序
@strColumnlist varchar(800), --要查询出的字段列表,*表示全部字段
@intPageSize int, --每页记录数
@intPageNum int, --指定页
@strWhere varchar(800) --查询条件
AS

DECLARE @sql nvarchar(4000) --用于构造SQL语句
DECLARE @where1 varchar(800) --构造条件语句
DECLARE @where2 varchar(800) --构造条件语句

DECLARE @intPageCount int --总页数
DECLARE @intRecordCount int --总记录数

set @intPageCount = 0
set @intRecordCount = 0

IF @strWhere is null or rtrim(@strWhere)= ' '
-- 为了避免SQL关键字与字段、表名等连在一起,首先为传入的变量添加空格
BEGIN --没有查询条件
SET @where1= ' WHERE '
SET @where2= ' '
END
ELSE
BEGIN --有查询条件
SET @where1= ' WHERE ( '+@strWhere+ ') AND '
SET @where2= ' WHERE ( '+@strWhere+ ') '
END

set @strColumn = ' ' + @strColumn + ' '
set @strColumnlist = ' ' + @strColumnlist + ' '

--计算总记录条数
SET @sql= 'SELECT @intRecordCount=COUNT(*) FROM ' + @strTable + @where2
EXEC sp_executesql @sql,N '@intRecordCount int OUTPUT ',@intRecordCount OUTPUT

--构造SQL语句,计算总页数。计算公式为 总页数 = Ceiling ( 记录个数 / 页大小 )

SET @sql= 'SELECT @intPageCount=CEILING((COUNT(*)+0.0)/ '
+ CAST(@intPageSize AS varchar)
+ ') FROM ' + @strTable + @where2

--执行SQL语句,计算总页数,并将其放入@intPageCount变量中

EXEC sp_executesql @sql,N '@intPageCount int OUTPUT ',@intPageCount OUTPUT

--将总页数放到查询返回记录集的第一个字段前,此语句可省略
--SET @strColumnlist= Cast(@intPageCount as varchar(30)) + ' as PageCount, ' + @strColumnlist


IF @intOrder=0 --构造升序的SQL

SET @sql= 'SELECT TOP '+ CAST(@intPageSize AS varchar) +
@strColumnlist +