-
- 一种效率极高的ASP分页思想[ZT]
- Weather:好晴朗啊....
- 2004-08-25
在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 - 合计纪录数
[QUOTE]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 提示没有纪录并返回 [/QUOTE]
------- 计算部分 -----------
[QUOTE]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 [/QUOTE]
------- 显示子程序 -----------
[QUOTE]sub show(i)
response.write 显示的内容
end sub%>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>test</title>
</head> [/QUOTE]
------- 数据显示部份 -----------
[QUOTE]<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> [/QUOTE]
四、测试对比
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
盼各位高人指教,谢谢。-
Views(3891) | Comments(14) |
In:
web develop
|
(08/23)
ASP应用之模板采用
[一种效率极高的ASP分页思想[ZT]]的回复
-
大雾
于
2004-08-28 20:23:35
发表 |
IP:222.45.88.*
- 青蛙柠檬漆,哼哼偶新改的叶子http://www.blogcn.com/User7/joy_xiaozhu720/index.html这会应该避免一些失误咯~~~哼哼
-
柠檬园主
于
2004-08-29 12:14:14
发表 |
IP:210.83.202.*
- 汗...我现在打不开呀.真想看看你到底改成啥样子了...
改好了的话,偶给你加上偶的链接里面去.
-
大大雾
于
2004-08-29 23:06:15
发表 |
IP:222.45.89.*
- 哼~~好了才加~~假了吧~~RE同学都能打开,你能打不开吗?哼哼~~~~[em18]
- 4# 柠檬园主 于 2004-08-30 08:56:04 发表 | IP:210.83.202.*
- 好好,给你加上,小样儿,你上次的那个确实是太乱了,这次还好.不过我昨天也确实打不开,可能是我们的网不好昨天,嗯嗯,现在给小雾加上喽....
- 5# re 于 2004-08-30 10:03:02 发表 | IP:218.79.253.*
- 你怎么知道我能够打开的?
我确实是去打开了,可是想留言需要先注册,我输了个帐号竟然说存在,就算了。
- 6# 大大大雾 于 2004-08-30 21:36:03 发表 | IP:222.45.89.*
哼~~互加
哼哼互相学习嘿嘿~~
RE留的大名在上面瞎子都看的到~~何况偶不是瞎子
还有是不能中文留名字`~偶用的是最原始的博客,所以不搬家咯~~
声明:俺是大雾!!!
- 7# re 于 2004-09-10 17:12:19 发表 | IP:211.160.163.*
- 啊,我怎么没记得我留了言的呀。诶,再去仔细找找。
- 8# littlenew 于 2007-07-13 17:12:31 发表 | IP:219.134.19.*
看一下这个问题能不能解决。
我不知道改动了什么服务 , 我的ASP程序只要改动一点,就必须得重启IIS,才能看到修改后的效果,这是怎么回事。急呀,
- 9# 柠檬园主 于 2007-07-13 23:49:05 发表 | IP:221.201.165.*
可能是你IE的选项里的Internet临时文件的设置有问题吧,是不是设置成了更新不检查了?
再不行把网站属性里的目录》配置》选项里的缓存的勾去掉。
- 10# littlenew 于 2007-07-14 11:19:43 发表 | IP:61.141.202.*
这样好像也不行呀,我都试了一下,不知道怎么回事。真是郁闷,难道这样也要重装系统吗?
- 11# littlenew 于 2007-07-16 11:32:51 发表 | IP:218.18.131.*
似乎是有点正常了,是卖咖啡的事。卸了。正常了。真的好晕呀。
- 12# 柠檬园主 于 2007-07-18 08:56:09 发表 | IP:59.44.76.*
哈哈,那是你的McAfee设置得不当了,我自己电脑用McAfee,服务器也用,都没事。
- 13# littlenew 于 2007-07-27 08:47:18 发表 | IP:218.18.131.*
说实话,卖咖啡确实不错,我也不想换掉它,但我基本上没有什么配置,就是不行。
,现在换了小红伞,感觉一般般,占内存特小。
- 14# 柠檬园主 于 2007-07-29 22:11:10 发表 | IP:221.201.145.*
可怜的McAfee呀...
