使用数据库分页的更高效方法 (数据库分页不用in)

随着数据量的不断增加,越来越多的网站和应用需要支持分页查询和显示。在传统的应用中,分页查询是由后成的,即数据库会对查询结果进行分页,然后返回给前端。但随着前端技术的发展,越来越多的分页逻辑被移到前端。这种方式可以提高系统的性能和用户的体验,但在大数据量的情况下,仍然存在效率问题。本文将讨论几种。

1. 增量分页

增量分页是指每次查询一页数据时,只查询比上一页数据的最后一条记录更早的记录。具体地说,可以在每次查询时,将上一次查询的记录的ID作为下一次查询的游标,在下一次查询中只返回ID比这个游标大的记录。这种方法的优点是查询速度快,因为数据库只需要比较ID的大小,而不需要扫描整个表。但缺点是如果有大量数据入和删除,游标可能会失效,需要重新查询。

2. 缓存分页

缓存分页是将分页数据缓存在系统中,并利用缓存提高分页查询的效率。具体而言,可以将分页结果保存在缓存中,下一次查询时可以从缓存中获取数据,而不必再次查询数据库。当用户进行操作,如新增、更新、删除时,需要更新缓存。此外,可以设置缓存失效时间,确保缓存一定时间内是最新的。

3. 预处理分页

预处理分页是指将所有分页数据一次性查询出来,然后根据页面需要展示的数据进行选择。当用户翻页时,不需要再次查询数据库,只需要把已经查询出来的数据进行重新排序和选择即可。这种方法可以减少数据库的查询次数,但可能会增加系统的内存和网络带宽使用量。

4. 倒序分页

倒序分页是指将数据表按照倒序排列,然后使用LIMIT和OFFSET进行分页。具体而言,可以使用LIMIT语句指定每页显示的数据量,OFFSET语句指定跳过的数据量,然后按照倒序排列的数据进行查询。这种方法可以避免使用ORDER BY语句进行排序,速度较快,但需要在数据表的结构上进行更改。

使用数据库分页的方式有多种,可以根据不同的应用场景进行选择。基于查询速度和系统资源使用的考虑,增量分页和缓存分页可以实现效率的更大化。但对于数据量较大的场景,预处理分页可以减少数据库的查询次数,提高效率。而倒序分页则适用于数据表结构可以随意更改的情况,可以利用不同的排序方式实现更高效的分页。不同的分页方式应该根据具体需求和环境选择,以实现更高效的查询和展示。

相关问题拓展阅读:

数据库中in的用法

数据库中in的用法的用法你知道吗?下面我就跟你们详细介绍下数据库中in的用法的用法,希兆芦仔望对你们有用。

  数据库中in的用法的用法如下:

  IN:确定给定的值是否与子查询或列表中的值相匹配。

  IN 关键字使您得以选择与列表中的任意一个值匹配的行。

  SELECT ProductID, ProductName FROM Northwind.dbo.Products WHERECategoryID IN (1, 4, 5)

  IN 关族汪键字之后的项目必须用逗号隔开,并且括在括号中。

  NOT IN:通过 NOT IN关键字引入的子查询也返回一列零值或更多值。

  以下查询查找没有出版过商业书籍的出版商的名称。

  SELECTpub_name FROM publishers WHERE pub_id NOT IN (SELECT pub_id FROM titles WHEREtype = ‘business’)

 哗余 使用 EXISTS和 NOT EXISTS引入的子查询可用于两种原理的操作:交集与差集。两个的交集包含同时属于两个原的所有元素。

  差集包含只属于两个中的之一个的元素。

  EXISTS:指定一个子查询,检测行的存在。

  SELECT DISTINCT pub_name FROM publishers WHERE EXISTS (SELECT *FROM titles WHERE pub_id = publishers.pub_id AND type =

  ’business’)

  SELECTdistinct pub_name FROM publishers WHERE pub_id IN (SELECT pub_id FROM titlesWHERE type = ‘business’)

  两者的区别:

  EXISTS:后面可以是整句的查询语句如:SELECT *FROM titles

  IN:后面只能是对单列:SELECTpub_id FROM titles

  NOT EXISTS:

  例如,要查找不出版商业书籍的出版商的名称:

  SELECTpub_name FROM publishers WHERE NOT EXISTS (SELECT * FROM titles WHERE pub_id =publishers.pub_id AND type =

  ’business’)

  下面的查询查找已经不销售的书的名称:

  SELECT titleFROM titles WHERE NOT EXISTS (SELECT title_id FROM sales WHERE title_id =titles.title_id)

  例子:

  //验证有发布产品的公司个数

  select id,name from company where exists (select * from product where comid=company.id)

  select id,name from company where id in(select comid from product)

  //验证没有发布产品的公司个数

  select id,name from company where not exists (select * from product where comid=company.id)

  select id,name from company where id not in(select comid from product)

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;数据库分页不用in的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于数据库分页不用in,使用数据库分页的更高效方法,数据库中in的用法,mysql数据库分页的信息别忘了在本站进行查找喔。


数据运维技术 » 使用数据库分页的更高效方法 (数据库分页不用in)