存档

文章标签 ‘分页’

一个关于分页的面试题

2015年5月1日 5 条评论

在网上看到面试中考分页的帖子,结合自己的想法,集合一下,欢迎讨论。

分页是各式各样系统开发过程中必不可少的环节,普通web应用数据量小、访问量小,分页可以用简单的方式来实现,一般是通过startrow+pagenum来实现,甚至可以提前生成静态页面,这样数据库基本没有压力,缺点是数据变动时要重新生成所有列表页,而且不能实时显示数据的变化。

不过还好的是对于大多数的应用能够实现需求即可,不必过多考虑优化。

互联网公司的海量数据,情况就变得不一样了,更多考虑的是性能和效率,加载速度提高一点点,就意味着用户体验的提升,用户体验决定着产品的未来。

因此我们可以看到数据量变大的情况下一个高效的分页变的重要程度,分页面试能够体现面试者是否处理过大量数据,没处理过也能够体现其面试时处理问题的思考和应变能力。

不管什么方法做分页,它都离不开数据库的支持,优化原则是尽量减少扫描数据库中记录的条数。

常用的关系数据库mysql和oracle为例:mysql分页依赖于limit,oracle分页使用rownum实现。

mysql分页方法?

mysql分页的核心语句:

先看一下分页的基本原理(CSDN那个百万级数据库来测试!):

SELECT * FROM csdn ORDER BY id DESC LIMIT 100000,2000;
耗时: 0.813ms

分析:对上面的mysql语句说明:limit 100000,2000的意思扫描满足条件的102000行,扔掉前面的100000行,返回最后的2000行。

问题就在这里,如果是limit 100000,20000,需要扫描120000行,在一个高并发的应用里,每次查询需要扫描超过100000行,性能肯定大打折扣。

在《efficient pagination using mysql》中提出的clue方式。

利用clue方法,给翻页提供一些线索,比如还是SELECT * FROM csdn order by id desc,按id降序分页,每页2000条,当前是第50页,当前页条目id最大的是102000,最小的是100000。如果我们只提供上一页、下一页这样的跳转(不提供到第N页的跳转)。

那么在处理上一页的时候SQL语句可以是:
SELECT * FROM csdn WHERE id<=102000 ORDER BY id DESC LIMIT 2000; #上一页 耗时:0.015ms 处理下一页的时候SQL语句可以是: SELECT * FROM csdn WHERE id>102000 ORDER BY id ASC LIMIT 2000; #下一页
耗时:0.015ms

这样,不管翻多少页,每次查询只扫描20行。效率大大提高了!

但是,这样分页的缺点是只能提供上一页、下一页的链接形式。

oracle如何分页?

oracle分页的核心:

大量数据时oracle分页语句的优化(通过rownum和rowid来进行分页),如下:

分类: mysql, oracle 标签:

mongodb非skip高效php分页类

2014年1月19日 1 条评论

mongodb分页skip+limit分页要先查出所有结果再去跳过,这样如果查询页面越往后效率越低。

如果能够通过查询条件查出每页结果的最后一条记录,在用最后一条记录作为查询条件去查下一页,这样每次都查询页面size条记录,效率子让不会差。

具体代码如下:包含mongodb.class.php, page.class.php, test.php
mongodb.class.php mongodb 操作类

page.class.php mongodb分页逻辑类

test.php 测试代码

分类: php 标签: , , ,