一种效率极高的ASP分页思想

一种效率极高的ASP分页思想
发表:2005-11-15  点击: 42次  作者:  转自:3rgb.com
  在ASP中显示大量数据时的翻页问题已经有不少文章介绍过了,一般情况下利用ADO页定位方法实现翻页功能。但随着数据库内容增多,翻页的效率问题就突出了,ADO的页定位方法速度明显地有些令人不能容忍。 

  为了找到一种高效率的翻页方法,我分析了常见的几种ADO页定位方法,发现在翻页前都要利用查询语句把符合条件的纪录读出,放入RecordSet集合,然后再进行翻页的计算和操作。如果符合条件的纪录数大于你设定的每页显示纪录数,则多出来的纪录虽然已经读出但却没有用上,在翻到下一页时,又重新查询数据库。也就是说,如果你找到符合要求的500条纪录,查询时读出了500条纪录,但每页只显示20条纪录,这就有480条纪录读出后没用,翻页时又重复上述操作。众所周知,从数据源读取数据的操作是很费时间的,更何况读出来的数据大部份用不上呢?于是,我想如果每次只读出符合条件的、数量不超过每页显示条数的纪录应该是效率最高的,顺着这个思路又考虑到翻页所必需的条件,就产生了记住每页两端的记录号、翻页时只从端点读取每页显示条数的分页方法。 

  由于接触ASP的时间不长,从思路到实现还有一段距离,故在一个论坛中提出了这个想法与大家讨论,经过该论坛版主和网友们的分析、建议和指教逐步完成了这段代码,在我的老PII机器上进行检测,效果比较明显。在此特详细思路、解决办法、代码贴出请各位高人指教。 

一、原则 
1.每次刷新页面时根据翻页的方向,只读取自id1或id2开始的rows条纪录。 
2.显示查询结果时用for/next循环,不用where not rs.eof and i<=rows/loop循环,目的是在循环时不检验rs.eof以提高速度。 
3.当纪录的序号不连续时也能正常完成翻页功能。 

二、方法 
1.数据表中建立一个自动编号字段ID用以识别纪录号。 
2.第一次查询时读出所有符合条件的纪录,用以计算有多少页(max)和多少条纪录(num),以后查询时每次只读出rows条纪录,并且不做重复计算。 
3.用sql语句的TOP rows格式来读出所需要的数据,翻页的主要工作在这里完成。 
4.向前翻页时用降序排序的方法实现。 
5.用url转移时带上每页的页号、两端的端点号、最大页数、最大纪录数。 

  开始写代码的时候用过复合查询、升序排序等种种办法,结果均不理想,翻页经常翻到岔路上去,主要问题是如果用where ID<id1 则数据是从ID=0开始的rows条纪录,直接显示了第一页,没有达到向前翻页的目的;如果用降序排序,则数据是从ID<=id1开始的,但向后翻页的端点id2<id1,造成了混乱。当时直埋怨作系统的为何不来个Bottom N或Last N之类的指令,那就简单多了。试了几次后突然想到一个笨办法:既然是降序排序,在显示的时候反过来循环不就一切正常了?看来最简单的办法也可能是最有效的办法。另外,我认为除了用记忆端点分页的可以提高效率外,程序是否精炼,也会影响到速度。 

这段代码没有考虑页面跳转的功能,我想除了论坛以外,如果是资料查询检索,页面跳转的用处不大,尤其是向后跳转。至于向前跳转,在代码中加入一些指令实现起来不难。 

三、代码 

------- 读取数据部分 ----------- 

id1,id2 - 页端点号,sn - 当前页号,sp - 上一页号, rows - 每页显示条数,go - 翻页方向(* 表示向回翻),max - 合计页数,num - 合计纪录数 


dim id1,id2,sn,rows,go,sql,max,num 
sql="select * from 数据表 where 查询条件" 
go=request("go") 
sn=1 
rows=10 
id1=request("id1") 
if id1<>"" then 
sql=left(sql,6)&" top "&rows&right(sql,len(sql)-6) 
if go="*" then 
  sn=request("sp")-1 
  sql=sql & " and ID<"&id1&" order by ID desc" 
else 
  sn=request("sp")+1 
  id2=request("id2") 
  sql=sql & " and ID>"&id2 
end if 
end if 
Set Rs=server.createobject("ADODB.Recordset") 
Rs.open sql,conn,3,1 
if Rs.eof or Rs.bof then 提示没有纪录并返回

------- 计算部分 ----------- 

if id1="" then 
num=Rs.recordcount 
max=int(num/rows+0.99) 
if max<1 then 
  rows=num 
  max=1 
end if 
else 
max=int(request("m")) 
num=request("n") 
end if 


------- 显示子程序 ----------- 

sub show(i) 
response.write 显示的内容 
end sub 

%> 
<html> 

<head> 
<meta http-equiv="Content-Type" content="text/html; charset=gb2312"> 
<title>test</title> 
</head>

------- 数据显示部份 ----------- 



<body> 
<div> 
<p>有【<%=num%>】条信息,第 <%=sn%> 页 共 <%=max%> 页</p> 
<hr size="1"> 
<ul> 
<% 
m=num-((sn-1)*rows) 
if m>rows then m=rows 
if go="*" then 
Rs.movelast 
id1=Rs("ID") 
for i=1 to m 
  show(i) 
  Rs.moveprevious 
next 
Rs.movenext 
else 
Rs.movefirst 
id1=Rs("ID") 
for i=1 to m 
  show(i) 
  Rs.movenext 
next 
Rs.moveprevious 
end if 
id2=Rs("ID") 
surl="test.asp?sp="&sn&"&m="&max&"&n="&num&"&id1="&id1&"&id2="&id2 
rs.close 
set rs=nothing 
conn.close 
set conn=nothing 
</ul> 
<hr size="1"> 
<table cellpadding="0" cellspacing="0" width="100%"> 
  <tr> 
    <td width="80%"></td> 
    <td width="10%"><%if sn>1 then response.write "<a href='"&surl&"&go=*'>上一页</a>"%> 
</td> 
    <td width="10%"><%if sn<max then response.write "<a href='"&surl&"'>下一页</a>"%> 
</td> 
  </tr> 
</table> 
</div> 
</body> 
</html> 

四、测试对比 

5万条纪录的Access数据库(大小为26.2M),用了几种方法分别进行运行时间测试,结果如下: 

------------------------------------------ 
页号 |ADO页定位|Bookmark|list.asp|记忆端点 
------------------------------------------ 
1  10.66   10.98  10.71  9.71 
2  6.59     7.48  6.70   0.66 
3  6.42     7.73  6.58   0.27 
4  6.53    7.68  6.48   0.27 
5  6.37    7.68  6.60   0.33 
6  6.65    7.52  6.58   0.33 
7  6.41    7.53  6.49   0.27 
8  6.36    8.19  6.64   0.27 
9  6.31    7.85  6.54   0.33 
10  6.43    7.58  6.53   0.33 
11  6.48    7.57  6.53   0.33 
10  6.43    7.53  6.63   0.38 
9  6.54    7.64  6.53   0.33 
8  6.41    7.57  6.58   0.33 
7  6.42    7.68  6.53   0.32 
6  6.42    7.57  6.48   0.33 
5  6.41    7.65  6.63   0.27 
4  6.37    7.62  6.48   0.33 
3  6.48    7.59  6.47   0.32 
2  6.75    7.60  6.52   0.28 
1  6.53    7.61  6.48   0.32 
------------------------------------------ 
list.asp是论坛中ywd1520朋友提供的从动网里分离出来的分页程序,bookmark是某版主朋友提供的分页程序,时间单位:秒。 

测试环境: 
清除所有缓存文件,用相同的页面和查询条件,检索出5万条符合要求的纪录,顺序翻页,先向后再向前。每页10条纪录,每条纪录4个字段。 
硬件配置:PII350超外频至133M使用,256M SDRAM内存,5.1G昆腾硬盘 
操作系统:WinMe, PWS, MS Access2000 

盼各位高人指教,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值