黑马程序员技术交流社区

标题: 关于分页的疑问? [打印本页]

作者: 冯盼    时间: 2012-12-3 13:29
标题: 关于分页的疑问?
用Sql语句可以实现分页效果,用Repter也能达到分页效果,到底用哪个更好呢?
作者: 刘亚龙    时间: 2012-12-3 13:46
Repeter默认没有分页效果吧,listview有分页的选项,但是listview的默认分页方法是每次启用分页都会把数据库中所有的数据都取到服务器内存中,然后在内存中再计算出需要的数据返回给客户端。当数据库中数据量比较大时,这种方法对服务器CPU和内存的消耗非常严重,如果用户访问量也很高,服务器就更吃不消了。一种可行的方法就是数据库中取数据时使用row_number()。数据库会在内部进行处理然后直接返回请求的一段数据,这样对服务器CPU和内存的消耗减少很多。
使用Repeter实现分页效果也是通过row_number()进行高效分页,然后把得到的数据集绑定给Repeter。
作者: 王斌    时间: 2012-12-3 17:22
本帖最后由 王斌 于 2012-12-3 17:24 编辑

表中主键必须为标识列,[ID] int IDENTITY (1,1)
  1.分页方案一:(利用Not In和SELECT TOP分页)
语句形式:   
SELECT TOP 10 *
FROM TestTable
WHERE (ID NOT IN
          (SELECT TOP 20 id
         FROM TestTable
         ORDER BY id))
ORDER BY ID


SELECT TOP 页大小 *
FROM TestTable
WHERE (ID NOT IN
          (SELECT TOP 页大小*页数 id
         FROM 表
         ORDER BY id))
ORDER BY ID
   2.分页方案二:(利用ID大于多少和SELECT TOP分页)
语句形式:  
SELECT TOP 10 *
FROM TestTable
WHERE (ID >
          (SELECT MAX(id)
         FROM (SELECT TOP 20 id
                 FROM TestTable
                 ORDER BY id) AS T))
ORDER BY ID


SELECT TOP 页大小 *
FROM TestTable
WHERE (ID >
          (SELECT MAX(id)
         FROM (SELECT TOP 页大小*页数 id
                 FROM 表
                 ORDER BY id) AS T))
ORDER BY ID
  3.分页方案三:(利用SQL的游标存储过程分页)

create  procedure SqlPager
@sqlstr nvarchar(4000), --查询字符串
@currentpage int, --第N页
@pagesize int --每页行数
as
set nocount on
declare @P1 int, --P1是游标的id
@rowcount int
exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1, @rowcount=@rowcount output
select ceiling(1.0*@rowcount/@pagesize) as 总页数--,@rowcount as 总行数,@currentpage as 当前页
set @currentpage=(@currentpage-1)*@pagesize+1
exec sp_cursorfetch @P1,16,@currentpage,@pagesize
exec sp_cursorclose @P1
set nocount off

其它的方案:如果没有主键,可以用临时表,也可以用方案三做,但是效率会低。
建议优化的时候,加上主键和索引,查询效率会提高。

通过SQL 查询分析器,显示比较:我的结论是:
分页方案二:(利用ID大于多少和SELECT TOP分页)效率最高,需要拼接SQL语句
分页方案一:(利用Not In和SELECT TOP分页)   效率次之,需要拼接SQL语句
分页方案三:(利用SQL的游标存储过程分页)    效率最差,但是最为通用         




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2