数据库应用有用的技巧:分页实现 (数据库应用 –分页实现)

随着互联网和移动互联网的发展,数据量急剧增长,数据库的应用变得越来越普及和必要。数据库应用的一个关键问题是如何快速高效地查询和展示数据,特别是对于大量数据的情况下。分页查询是一个解决这个问题的常见方法,下面将对分页查询的实现进行详细介绍。

一、分页查询的基本原理

分页查询是指将大量的数据按照一定的规则进行分割,每次只查询一部分数据,这样可以减少数据库查询的负担,提高查询速度,同时也可以一定程度上避免数据重复查询。分页查询需要指定每页显示的记录数和当前要查询的页数。其基本原理如下:

1. 计算总页数:总页数=总记录数/每页显示的记录数,对总记录数进行取整操作(向上取整或向下取整)得到总页数。

2. 查询当前页的记录:根据当前页数和每页显示的记录数计算出需要查询的记录范围(起始记录数和结束记录数),然后查询这个范围内的记录数据。

3. 显示当前页的记录:将查询到的记录数据按照一定的格式展示在前端页面上,同时需要提供翻页功能,方便用户浏览其他页面的数据。

二、分页查询的实现方法

分页查询可以使用多种方式实现,下面介绍几种常见的分页查询方法:

1. LIMIT OFFSET 方法:

在 MySQL 数据库中,可以使用 LIMIT OFFSET 方法实现分页查询。例如查询前 10 条数据:SELECT * FROM table LIMIT 0,10;查询第 11 ~ 20 条数据:SELECT * FROM table LIMIT 10,10。其中,LIMIT 后面的之一个参数表示查询数据的起始位置(索引从 0 开始),第二个参数表示查询的数据数量。

2. ROW_NUMBER 方法:

ROW_NUMBER 是一个关键字,在 SQL Server 和 Oracle 数据库中都适用。通过 ROW_NUMBER,可以为每行数据附上一个序号,再根据序号进行分页查询。例如查询前 10 条数据:SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY id DESC) AS RowNumber,* FROM table ) AS T WHERE T.RowNumber BETWEEN 1 AND 10;查询第 11 ~ 20 条数据:SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY id DESC) AS RowNumber,* FROM table ) AS T WHERE T.RowNumber BETWEEN 11 AND 20。

3. 数据库函数方法:

MySQL 和 Oracle 数据库均提供了内置函数实现分页查询功能。例如 MySQL 数据库使用 limit 函数:SELECT * FROM table LIMIT 0,10;Oracle 数据库使用 rownum、select、from、where 条件语句联合查询:SELECT * FROM (SELECT rownum rn ,a. * FROM table a WHERE rownum = 1。

4. Hibernate 分页查询:

Hibernate 是一种流行的 ORM 框架,可以方便地进行分页查询。在 Hibernate 中,使用分页器(Pager)来查询每页数据。示例代码如下:

Query query = session.createQuery(“FROM User”); // 查询全部数据

pager.setTotalCount(query.list().size()); // 设置总记录数

query.setFirstResult((pager.getPageNo() – 1) * pager.getPageSize());

query.setMaxResults(pager.getPageSize());

pager.setDataList(query.list());

5. MyBatis 分页查询:

MyBatis 是一种常用的持久层框架,在其中使用分页插件 PageHelper 可以轻松实现分页查询。示例代码如下:

PageHelper.startPage(pageNum,pageSize);

List users = userMapper.list(); // 查询全部数据

PageInfo pageInfo = new PageInfo(users);

return pageInfo;

三、分页查询的优化

分页查询在实现时需要注意一些性能优化的问题,尽可能减少对数据库的压力,提高查询效率。下面介绍一些优化方法:

1. 不要查询全部数据:在进行分页查询时,不必将全部数据一次性查询出来,而是应该只查询一页数据。可以使用 LIMIT、ROW_NUMBER 等方式查询指定数据范围内的数据。

2. 避免大量重复查询:在进行分页查询时,多次查询同一范围内的数据是一种浪费资源的操作,可以使用缓存技术、排序、索引等方式避免重复查询。

3. 选取适当的数据结构:在进行分页查询时,可以使用适当的数据结构来加快查询速度,例如使用数据库索引可以避免全表扫描,提高查询效率。

4. 控制多线程的并发数量:当应用采用多线程方式访问数据库时,为避免并发冲突和效率浪费,应该控制并发数量,避免过多访问数据库。

相关问题拓展阅读:

mysql数据库分页

可以空知型使用TOP分页啊

什么斗猜数据库都猛高可以用的

例如:

select

top

*

from

a

where

a.id

not

in

(select

top

(5

*

1) id

from

b)

一页要获取的条数

是页数

1代表的是第二页

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

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

SELECT *

FROM city

ORDER BY id DESC

LIMIT 0, 15

这个查询耗时0.00sec。So,这雀则个查询有什么问题呢?实际上,这个查询语句和参数都没有问题,因为它用到了下面表的主键,而且只读取15条记录。

CREATE TABLE city (

id int(10) unsigned NOT NULL AUTO_INCREMENT,

city varchar(128) NOT NULL,

PRIMARY KEY (id)

) ENGINE=InnoDB;

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

SELECT *

FROM city

ORDER BY id DESC

LIMIT, 15;

上面的查询在有2M行记录时需要0.22sec,通过EXPLAIN查看SQL的执行计划可以发现该SQL检索了100015行,但最后只需要15行。大的分页偏移量会增加使用的数据,MySQL会将大量最终不会使用的数据加载到内存中。就算我们假设大部分网站的用户只访问前几页数据,但少量的大的分页偏移量的请求也会对整个系统造成危害。Facebook意识到了这一点,但Facebook并没有为了每秒可以处理更多的请求而去优化数据库,而是将重心放在将请求响应时间的方差变小。

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

SELECT COUNT(*)

FROM city;

然而,上面的SQL在采用InnoDB为存储引擎时需要耗费9.28sec。一个不正确的优化是采用 SQL_CALC_FOUND_ROWS,SQL_CALC_FOUND_ROWS 可以在能够在分启岁历页查询时事先准备好符合条件的记录数,随后只要执行一句 select FOUND_ROWS(); 就能获得总记录数。但是在大多数情况下,查询语句简短并不意味着性能的提高。不幸的是,这种分页查询方式在许多主流框架中都有用到,下面看看这个语句的查询性能。

SELECT SQL_CALC_FOUND_ROWS *

FROM city

ORDER BY id DESC

LIMIT, 15;

这个语句耗时20.02sec,是上一个的两倍。事实证明使用 SQL_CALC_FOUND_ROWS 做分页是很糟糕的想法。

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

高效的计算行数

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

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

SELECT COUNT(*)

FROM city

USE INDEX(PRIMARY);

获取记录

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

CREATE TABLE news(

id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,

title VARCHAR(128) NOT NULL

) ENGINE=InnoDB;

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

SELECT *

FROM news WHERE id $last_id

ORDER BY id ASC

LIMIT $perpage

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

SELECT id

FROM (

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

FROM news

JOIN (SELECT @cnt:= 0)T

WHERE id = $offset

ORDER BY OFFSET

LIMIT $perpage;

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

select

*

from

数据表

order

by

id

limit

$num,$pages;

$num

//(当前页数-1)乘以每页胡早条数

$pages//每页条数

这样就陪搭可以了

首页

$page=1

下一页

$page=$_GET+1;

上芦做拿一页

$page=$_GET-1;数据库应用 –分页实现的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于数据库应用 –分页实现,数据库应用有用的技巧:分页实现,mysql数据库分页的信息别忘了在本站进行查找喔。


数据运维技术 » 数据库应用有用的技巧:分页实现 (数据库应用 –分页实现)