Heim > Datenbank > MySQL-Tutorial > access的分页查询效率问题

access的分页查询效率问题

WBOY
Freigeben: 2016-06-07 15:30:45
Original
1172 Leute haben es durchsucht

本文 解决 的 问题 : 1.ACCESS是否存在更有 效率 的分页方法? 2.现有ACCESS大 数据 量10万条数据分页的 效率 测试 3.ACCESS的数据承载量到底有多大? 相信很多ASP的站点还在使用access数据库,因为access数据库无须开专门的数据库 空间 ,调用,迁移也方便

本文解决问题
1.ACCESS是否存在更有效率的分页方法?
2.现有ACCESS大数据量10万条数据分页的效率测试
3.ACCESS的数据承载量到底有多大?

    相信很多ASP的站点还在使用access数据库,因为access数据库无须开专门的数据库空间,调用,迁移也方便,节省费用。另外对网站搭建者的专业能力要求也相对低一些。但随着网站的运行,数据库体积越来越大,数据量也从最初的几百条到了现在的上万条,上十万条甚至更多。于是因数据应用级别的改变带来的各种各样的应用问题出现了。而其中大数据量的列表分页效率问题更是让很多人头疼。笔者随便通过“大数据量分页效率”,“access 分页”等关键词分别百度和谷歌了一下,发现有此疑问的大有人在。很多网页上也给出了不同的解决办法。那么,这些方法到底能达到优化效率,提高速度的目的吗?
    先让我们来看看以下的几个access分页优化方案,当然如果你直接将数据库升级到sql server,那么有更好的诸如存储过程等方法。今天我们就讨论一下access大数据量优化分页方法,以及access到底能承受多少数据量。
方案一:利用ado本身的结果集的pagesize,AbsolutePage的属性来进行分页
程序示例:(仅供示意,完善的各种条件判断自行添加)
MaxPerPage=20
page=cint(request("page"))

sql="select * from 表 where 条件 order by 排序条件"
set rst=server.CreateObject("adodb.recordset")
rst.open sql,conn,1,1
rst.pagesize=MaxPerPage
rst.AbsolutePage = Page   '将记录定位到对应页数的第一条
for i=1 to MaxPerPage
    循环列表
    rst.movenext
    if rst.eof then exit for
next

这个方法是最为常用的access分页方法。
缺点:每次都要读入符合条件的所有记录,然后再定位于对应页的记录。当数据量大的时候,效率就十分的低下。
与此相似的方法是利用ado的move方法,每次将记录集游标移动 (page-1)*pagesize ,就实现了了记录的分页。经过测试,效率与方案一大致相同。

方案二:
1.设置一个自增长字段.并且该字段为INDEX.
2.由于是 ACCESS ,所以,只能是前台分页.自增长字段目的,就是为了实现分页功能.
    1> 记录用户前页的最后一个 自增值 ,例如 M .
  2> 下一页,取下一页的开始值.M+1 ,结束值: M+1+1.5*PAGESIZE (注:由于数据库会有增删操作,故应该取页大小应该有一个系数,你可以根据情况自定一个1大的系数.
  3> 前台循环取 RS 的前 PAGESIZE 条, 写到一个 新的RS中,并返回.

这个方案通过自增值来分部截取不同分页的数据列表,文中考虑到数据库有增删操作,所以加入了一个系数的概念,这是一个不得已的做法。这个方案可以保证分页效率,但只能运用于增删不太频繁(自增值字段相邻记录的值相差不多的情况)的数据表。

方案三:not in 方法。这个方案在很多网站上都转载。据说对于越往前的分页效率提高越明显。我一直有所怀疑,因为“not in”本身就是个耗费资源的算法。很难相信一个低效率的方法能提高大数据量分页的效率。示例如下:
sql="select top 12 * from 表 where Id not in(select top page*pagesize Id from 表 order by id desc) order by Id desc"
如果是第9页,每页20条即
select top 20 * from 表 where Id not in(select top 9*20 Id from 表 order by id desc) order by Id desc

原理即:选择top 20 的记录,条件是id不在前面分页的记录ID里。通过这种方式过滤掉前面分页的记录,然后通过top高效率的方式获取当页的记录。
“top”确实高效,但是“not in”呢?
于是我直接用这种方法测试了一下,测试条件:10万条数据。点击查询.......... MY GOD,长时间无响应,最后Ctrl+Alt+Delete 结束任务。再试,结果同样如此。于是改变一下测试条件,变成1000条数据,OK,结果显示非常顺利。
结论:如果你是大数据量分页,还是不要用这种方法,会死人的。

方案四:"select * from (select top "&pagesize&" * from (select top "&page*pagesize&" * from 表" order by id desc) order by id) order by id desc"
这个方法简单说来,就是选取当前页及小于当前分页的所有记录,再通过“Top”方式选取当前页的记录。
这个方法没有出现效率低的语句,虽然至少要select两次(示例select了三次是为了排序)。但是效率应该不错。且越靠前的分页应该越明显。
如果还想节省效率,可以只select两次。
假如记录ID为1-100,每页5条。现在显示第4页,排序为倒序。
执行顺序:
1) 选择前4页的数据,即100-81共20条数据
2) 从这20条数据中选择最小的5条,即81-85。
3) 将选择的5条按倒序排,即成为 85-81。

如果节省第三步也可,只不过显示变成
第一页:96,97,98,99,100
第二页:91,92,93,94,95
.
.
.
其实也不错。

光说没用,最终看测试结果。我在相同的数据条件,服务器配置下,分别对方案一中的两种方法和方案四进行了access分页效率测试,测试数据如下
测试条件:>10万条;pagesize=20;分页总数>5000页;顺便也进行了一下“select 部分字段”和“select 所有字段”的对比测试。

从上面的测试结果来看,方案三的优势还是比较明显的。而到5000页的效率基本上和前两种方法差不多,甚至仍然有一定得优势。

另外,很多人在写select语句时, 习惯 select * from 表,这不是一个好习惯。上面的access分页测试结果表明,还是按需索要,按需供应的好,需要什么字段,就select什么字段。能够极大的节省服务器资源。

很多网友提到ACCESS时都不免的轻视,“你还在用access?”,“还不换sql server?”,“用access你还想多快?”。其实在我的经验看来,即便是在10万条的应用级别上。access常常比sql server快。因为sql server需要额外连接,且多了一个带宽连接因素的影响(当然,网站服务器和数据库服务器运行速度和带宽都很OK,那没话说)。
sql server 在更高数据级别上的速度优势还是比较明显,毕竟与access不是一个级别的产品。

为了探索一下access数据库的极限。在40万条数据的情况下进行了上述分页测试。速度确实大打折扣。但是第三种方案在一万页内还是表现不错的。此时数据库已经达到400多兆。再结合之前处理过的几个4,500兆的access数据库。我认为40万条数据是access数据库在一般应用的一个界限,但不是极限。超过这个数,就需要在程序优化上做太多的工作。就有些不太值了。





原文出处点击查看。

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage