网站首页 > 文章中心 > 其它

mysql查找怎么分页

作者:小编 更新时间:2023-10-09 13:21:39 浏览量:81人看过

mysql 分表分页查询解决思路

我这里想了一个解决思路,可能还不完善,希望能抛转引玉.

mysql如何做分页查询?

很多应用往往只展示最新或最热门的几条记录,但为了旧记录仍然可访问,所以就需要个分页的导航栏.然而,如何通过MySQL更好的实现分页,始终是比较令人头疼的问题.虽然没有拿来就能用的解决办法,但了解数据库的底层或多或少有助于优化分页查询.

我们先从一个常用但性能很差的查询来看一看.

mysql查找怎么分页-图1

SELECT *

FROM city

ORDER BY id DESC

CREATE TABLE city (

id int(10) unsigned NOT NULL AUTO_INCREMENT,

PRIMARY KEY (id)

) ENGINE=InnoDB;

真正的问题在于offset(分页偏移量)很大的时候,像下面这样:

对于分页请求,还有一个信息也很重要,就是总共的记录数.我们可以通过下面的查询很容易的获取总的记录数.

mysql查找怎么分页-图2

SELECT COUNT(*)

FROM city;

SELECT SQL_CALC_FOUND_ROWS *

下面来看看到底如何优化.文章分为两部分,第一部分是如何获取记录的总数目,第二部分是获取真正的记录.

高效的计算行数

如果采用的引擎是MyISAM,可以直接执行COUNT(*)去获取行数即可.相似的,在堆表中也会将行数存储到表的元信息中.但如果引擎是InnoDB情况就会复杂一些,因为InnoDB不保存表的具体行数.

mysql查找怎么分页-图3

我们可以将行数缓存起来,然后可以通过一个守护进程定期更新或者用户的某些操作导致缓存失效时,执行下面的语句:

USE INDEX(PRIMARY);

获取记录

下面进入这篇文章最重要的部分,获取分页要展示的记录.上面已经说过了,大的偏移量会影响性能,所以我们要重写查询语句.为了演示,我们创建一个新的表"news",按照时事性排序(最新发布的在最前面),实现一个高性能的分页.为了简单,我们就假设最新发布的新闻的Id也是最大的.

CREATE TABLE news(

id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,

一个比较高效的方式是基于用户展示的最后一个新闻Id.查询下一页的语句如下,需要传入当前页面展示的最后一个Id.

FROM news WHERE id $last_id

LIMIT $perpage

查询上一页的语句类似,只不过需要传入当前页的第一个Id,并且要逆序.

ORDER BY id ASC

上面的查询方式适合实现简易的分页,即不显示具体的页数导航,只显示"上一页"和"下一页",例如博客中页脚显示"上一页","下一页"的按钮.但如果要实现真正的页面导航还是很难的,下面看看另一种方式.

SELECT id

FROM (

SELECT id, ((@cnt:= @cnt + 1) + $perpage - 1) % $perpage cnt

FROM news

JOIN (SELECT @cnt:= 0)T

WHERE id $last_id

LIMIT $perpage * $buttons

)C

WHERE cnt = 0;

通过上面的语句可以为每一个分页的按钮计算出一个offset对应的id.这种方法还有一个好处.假设,网站上正在发布一片新的文章,那么所有文章的位置都会往后移一位,所以如果用户在发布文章时换页,那么他会看见一篇文章两次.如果固定了每个按钮的offset Id,这个问题就迎刃而解了.Mark Callaghan发表过一篇类似的博客,利用了组合索引和两个位置变量,但是基本思想是一致的.

如果表中的记录很少被删除、修改,还可以将记录对应的页码存储到表中,并在该列上创建合适的索引.采用这种方式,当新增一个记录的时候,需要执行下面的查询重新生成对应的页号.

SET p:= 0;

UPDATE news SET page=CEIL((p:= p + 1) / $perpage) ORDER BY id DESC;

当然,也可以新增一个专用于分页的表,可以用个后台程序来维护.

UPDATE pagination T

JOIN (

SELECT id, CEIL((p:= p + 1) / $perpage) page

ORDER BY id

ON C.id = T.id

SET T.page = C.page;

现在想获取任意一页的元素就很简单了:

FROM news A

JOIN pagination B ON A.id=B.ID

WHERE page=$offset;

CREATE TEMPORARY TABLE _tmp (KEY SORT(random))

ALTER TABLE _tmp ADD OFFSET INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, DROP INDEX SORT,ORDER BY random;

此时此刻呢就可以向下面一样执行分页查询了.

FROM _tmp

WHERE OFFSET = $offset

ORDER BY OFFSET

LIMIT $perpage;

简单来说,对于分页的优化就是...避免数据量大时扫描过多的记录.

mysql如何实现分页

Mysql的分页关键点在查询时的 limit $iStart,$iEnd;//起初值与总长度

举例:selece * from myTable1 order by id desc limit 0,10;

从0开始取前10条数据,取第二页的内容时,limit 10,10;即可

如有疑问去博客加好友,不清楚的再问我,有时间我再写几篇这样的文章

mysql 数据量大的表如何做分页查询

直接用limit start, count分页语句, 也是我程序中用的方法:

select * from product limit start, count

再看我们取最后一页记录的时间

难怪搜索引擎抓取我们页面的时候经常会报超时,像这种分页最大的页码页显然这种时

间是无法忍受的.

从中我们也能总结出两件事情:

①.)limit语句的查询时间与起始记录的位置成正比

oracle和mysql的分页查询怎么写?

可以根据下面操作进行编写.

以上就是土嘎嘎小编为大家整理的mysql查找怎么分页相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!

版权声明:倡导尊重与保护知识产权。未经许可,任何人不得复制、转载、或以其他方式使用本站《原创》内容,违者将追究其法律责任。本站文章内容,部分图片来源于网络,如有侵权,请联系我们修改或者删除处理。

编辑推荐

热门文章