首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > asp.net >

至于高效分页

2011-12-17 
关于高效分页selecttop11@idIDfromTableselecttop10*fromTablewhereID @ID(公式:PageSize*(PageIndex-1

关于高效分页
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 @intPageCountint --总页数
DECLARE @intRecordCountint --总记录数

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 +
' FROM ' + @strTable + @where1 +


@strColumn + '> (SELECT MAX( '+@strColumn+ ') '+
' FROM (SELECT TOP '+ CAST(@intPageSize*(@intPageNum - 1) AS varchar) +
@strColumn + ' FROM '+ @strTable+@where2+ 'ORDER BY '+@strColumn+ ') t) ORDER BY '+ @strColumn

ELSE --构造降序的SQL

SET @sql= 'SELECT TOP '+ CAST(@intPageSize AS varchar) +
@strColumnlist+
' FROM '+ @strTable + @where1 +
@strColumn + ' <(SELECT MIN( '+@strColumn+ ') '+
' FROM (SELECT TOP '+ CAST(@intPageSize*(@intPageNum - 1) AS varchar) +
@strColumn + ' FROM '+ @strTable+@where2+ 'ORDER BY '+@strColumn+ ' DESC) t) ORDER BY '+
@strColumn + ' DESC '

IF @intPageNum=1--第一页

SET @sql= 'SELECT TOP '+CAST(@intPageSize AS varchar) + @strColumnlist + ' FROM '+@strTable+
@where2+ 'ORDER BY '+@strColumn+CASE @intOrder WHEN 0 THEN ' ' ELSE ' DESC '

END

EXEC(@sql)
print @sql
Select PageCount=@intPageCount,RecordCount=@intRecordCount
GO

[解决办法]
up
[解决办法]
帮你顶!
[解决办法]
好呀,学习,up
[解决办法]
USE AdventureWorks;
GO
WITH OrderedOrders AS
(SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (order by OrderDate)as RowNumber
FROM Sales.SalesOrderHeader )
SELECT *
FROM OrderedOrders
WHERE RowNumber between 50 and 60;

热点排行