分享
 
 
 

数据分页方法新思路,速度非常快![转帖]

王朝asp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

这篇文章要达到的目的就是,实现大数据分页浏览并最优化速度。

http://www.acnow.net/ ts

建立一个web 应用,分页浏览功能必不可少;这个问题也是长久以来最普遍的问题,目前也得到了较好的解决,其中象ASP 程序的分页算法有很多,比如使用ado 对象的PageSize 这些属性,按记录总数计算页,然后跳转记录集再输出;也有编写存储过程实现分页数据,这些方面各有优缺点,以下本人介绍一种应用实际项目中速度非常快的分页算法;

http://www.acnow.net/ ts

关键点:SQL (用TOP 和 自动编号 实现) http://www.acnow.net/ nE

页面脚本 (浏览器回退功能)

http://www.acnow.net/ ts

环境: http://www.acnow.net/ nE

IIS/SQL Server/Access http://www.acnow.net/ nE

表结构: http://www.acnow.net/ nE

create table 内容表 ( http://www.acnow.net/ nE

自动编号 IDENTITY(int, 1,1) not null, http://www.acnow.net/ nE

分类编码 <I>var</I>char(20) null, http://www.acnow.net/ nE

标题 <I>var</I>char(255) NULL, http://www.acnow.net/ nE

内容 <I>var</I>char(4000) null, http://www.acnow.net/ nE

时间 datetime null, http://www.acnow.net/ nE

)

http://www.acnow.net/ ts

实现原理: http://www.acnow.net/ nE

这个表设定了自动编号字段,这个字段的特性就是生成不重复的整形,包括删除了记录后该字段仍然保持‘流水性’(注:通常在系统表建设中,这种字段的运用很少,因为编号不能自由管理,但在这里使用它,主要是想在文章中省略编号维护的代码)。

http://www.acnow.net/ ts

分页: http://www.acnow.net/ nE

那么第一步,就是查询一个页的数据;如果有100笔记录,按20记录一页,那么通常的分页算法就是“页总数=总记录 除 分页的控制数 [有余数的话,页总数加一]”,这样的做法就导致必须产生所有记录的一个大记录集;从而,又有人提出了用存储过程的分页算法,前者是asp 脚本产生大记录集,这样速度相当慢,后者是杀鸡用牛刀,虽然我经常写存储过程,但根据我的思路会发现写存储过程完全多余。 http://www.acnow.net/ nE

http://www.acnow.net/ nE

在SQL 中,许多刚接触它的朋友都知道 Top 修饰关键字的作用;例如:select TOP 1 * from table1 --这样就实现从Table1表返回只有一条记录的记录集那么分页优化的最终目的就是避免产生过大的记录集,通过TOP 即可完全控制;现在查询表应该是 select Top 20 自动编号,标题,内容,时间 from 内容表。 http://www.acnow.net/ nE

http://www.acnow.net/ nE

但现在还有个问题,就是如何定位,Top 不可能自动给我们定位输出某个页,这就设计到了where 从句,根据一个特定条件输出正确的内容;注意:记录的 order by 排序是非常重要的,这个决定了这个算法的成败; http://www.acnow.net/ nE

http://www.acnow.net/ nE

这里的演示是DESC 方式,倒序排列,比如网站的软件更新,就是最近的更新放最前面,而这个就是倒序方式。

http://www.acnow.net/ ts

OK,下面来看看实际代码,首先要确定是否为起始页。

http://www.acnow.net/ ts

http://www.acnow.net/ nE

dim strSQL,i,endID,isBeginPage http://www.acnow.net/ nE

const Cnt_PageSize = 20 '定义每页记录的大小 http://www.acnow.net/ nE

'通过检查浏览器传递的Page 参数的值来判断是否为进入下一页的操作 http://www.acnow.net/ nE

isBeginPage = isEmpty(request("Page")) or request("Page")="" or request("Page")<>"next" http://www.acnow.net/ nE

'这里是分页的核心 http://www.acnow.net/ nE

if isBeginPage then '如果是起始页 http://www.acnow.net/ nE

'查询=列出分类编码等于参数flbm 的记录,按倒序排列,并只列出前 Cnt_PageSize 笔 (Cnt_PageSize是常量定义,比如20) http://www.acnow.net/ nE

strSQL = "select TOP " & Cnt_pageSize & " 自动编号,标题,内容,时间 from 内容表 where 分类编码= '" & TRIM(SQLEncode(request("flbm"))) & "' order by 自动编号 desc" http://www.acnow.net/ nE

else '如果不是起始页 http://www.acnow.net/ nE

if request("Page")="next" then '这里这样写是为了加强代码的表现,如果参数为next ,则表示取下页内容 http://www.acnow.net/ nE

'查询=列出分类编码等于参数flbm的记录并且要小于自动编号endID (endID也是参数),并倒序排列,并只列出前 Cnt_PageSize 笔 (Cnt_PageSize是常量定义,比如20) http://www.acnow.net/ nE

strSQL = "select TOP " & Cnt_pageSize & " 自动编号,标题,内容,时间 from 内容表 where 分类编码= '" & TRIM(SQLEncode(request("flbm"))) & "' and 自动编号<" & request("endID") & " order by 自动编号 desc" http://www.acnow.net/ nE

End if http://www.acnow.net/ nE

end if

http://www.acnow.net/ ts

'打开数据连接执行SQL 并建立记录集 http://www.acnow.net/ nE

set rs = Cnn.Execute(strSQL) http://www.acnow.net/ nE

if not rs.Eof then '这里写入判断是否为Eof 可以不要,但是,在这里却有它的特殊意义 http://www.acnow.net/ nE

call TableTitle '这里是自写的函数,用于建立表格标记 http://www.acnow.net/ nE

call beginTr '这里是建立表格tr标记

http://www.acnow.net/ ts

for i=0 to rs.fields.Count-1 '遍历记录集字段 http://www.acnow.net/ nE

call AddCol(rs(i).name) '输出字段名 http://www.acnow.net/ nE

Next http://www.acnow.net/ nE

http://www.acnow.net/ nE

call endTr

http://www.acnow.net/ ts

while not rs.eof '循环记录集内容,并输出 http://www.acnow.net/ nE

call beginTr

http://www.acnow.net/ ts

for i=0 to rs.fields.Count-1 http://www.acnow.net/ nE

call AddRow(ASPEncode(rs(i).value)) http://www.acnow.net/ nE

Next http://www.acnow.net/ nE

call endTr http://www.acnow.net/ nE

endID = rs("自动编号") '这里保存每次输出的自动编号值 http://www.acnow.net/ nE

rs.MoveNext http://www.acnow.net/ nE

Wend http://www.acnow.net/ nE

call TableBottom '到此为止,就简单的将记录集内容全部输出 http://www.acnow.net/ nE

'这里输出翻页标记,vbaIIF 是自写函数 http://www.acnow.net/ nE

原型为 <I>function</I> vbaIIF(a,b,c) http://www.acnow.net/ nE

if a then http://www.acnow.net/ nE

vbaIIF =b http://www.acnow.net/ nE

else http://www.acnow.net/ nE

vbaIIF =c http://www.acnow.net/ nE

end if http://www.acnow.net/ nE

end <I>function</I> http://www.acnow.net/ nE

http://www.acnow.net/ nE

上一页的实现是通过脚本调用浏览器的功能 history.back(1) 实现,那么回页时并不需要在服务器端重新生成数据,速度不用考虑了。 http://www.acnow.net/ nE

在首页的时候,上一页的链接应该是无效的,通过 vbaIIF(isBeginPage,"disabled","") 实现,如果为首页,那么在标记中加入 disabled 属性 ,如果不是首页,则加入history.back(1); 脚本指令,用于回退浏览页。 http://www.acnow.net/ nE

下一页是传递Page 参数和endID参数,Page 设置为 next 表示为下一页的动作,endID 表示当前记录集的末尾编号,下页将由此分页。 http://www.acnow.net/ nE

http://www.acnow.net/ nE

response.Write("〈a href=""#"" onclick=""java<I>script</I>:" & vbaIIF(isBeginPage,"","history.back(1);") & """ " & vbaIIF(isBeginPage," disabled ","") & "〉上一页〈/a〉|〈a href=""TypeOptions.asp?flbm=" & request("flbm") & "&Page=next&endID=" & endID & """〉下一页〈/a〉") http://www.acnow.net/ nE

else http://www.acnow.net/ nE

'这里通过判断记录集是否为空来解决到末尾页还可以继续翻页的问题 http://www.acnow.net/ nE

if not isBeginPage then http://www.acnow.net/ nE

'判断是否为空记录,并且不是起始页,那么生成回退页面的脚本,效果就是进入该页后将自动返回到上页。 http://www.acnow.net/ nE

response.Write "〈<I>script</I> language=java<I>script</I>〉" & vbCrlf http://www.acnow.net/ nE

Response.Write "history.back(1);" & vbCrlf http://www.acnow.net/ nE

Response.Write "〈/<I>script</I>〉" http://www.acnow.net/ nE

Response.End http://www.acnow.net/ nE

else '如果是起始页记录就为空,则提示无内容 http://www.acnow.net/ nE

Response.Write "〈font color=blue〉该类别下无内容〈/font〉" http://www.acnow.net/ nE

end if http://www.acnow.net/ nE

end If

http://www.acnow.net/ ts

http://www.acnow.net/ nE

总结:通过前台脚本,SQL查询技巧,实现高性能的分页程序简单快速

http://www.acnow.net/ ts

希望同行提出更优秀实时数据分页算法

http://www.acnow.net/ ts

备注:由于论坛限制了HTML字符,所以关键符号采用了中文大写。

http://www.acnow.net/ ts

作者:萧寒 (chinasf) http://www.acnow.net/ nE

!QQ:410000 http://www.acnow.net/ nE

e-mail:chinasf@hotmail.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有