首页

文章

mysql数据库分页

发布网友 发布时间:2022-04-19 21:50

我来回答

4个回答

懂视网 时间:2022-04-07 21:25

    1、Oracle分页查询写法:
    select * from (select rownum,name from table where rownum <=endIndex )  
    where rownum > startIndex 


    2、DB2分页查询
    SELECT * FROM (Select 字段1,字段2,字段3,rownumber() over(ORDER BY 排序用的列名 ASC) AS rn from 表名) AS a1 WHERE a1.rn BETWEEN 10 AND 20 
    以上表示提取第10到20的纪录
    select * from (select rownumber() over(order by id asc ) as rowid from table where rowid <=endIndex )  
    where rowid > startIndex
    
    3、MySQL分页查询    
    select   *   from   table   limit   start,pageNum 

数据库DB分页查询

标签:数据库分页查询

热心网友 时间:2022-04-07 18:33

很多应用往往只展示最新或最热门的几条记录,但为了旧记录仍然可访问,所以就需要个分页的导航栏。然而,如何通过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 100000, 15;

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

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

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 100000, 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 DESC
LIMIT $perpage

查询上一页的语句类似,只不过需要传入当前页的第一个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 < $last_id
ORDER BY id DESC
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
FROM news
ORDER BY id
)C
ON C.id = T.id
SET T.page = C.page;

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

SELECT *
FROM news A
JOIN pagination B ON A.id=B.ID
WHERE page=$offset;

还有另外一种与上种方法比较相似的方法来做分页,这种方式比较试用于数据集相对小,并且没有可用的索引的情况下—比如处理搜索结果时。在一个普通的服务器上执行下面的查询,当有2M条记录时,要耗费2sec左右。这种方式比较简单,创建一个用来存储所有Id的临时表即可(这也是最耗费性能的地方)。

CREATE TEMPORARY TABLE _tmp (KEY SORT(random))
SELECT id, FLOOR(RAND() * 0x8000000) random
FROM city;

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

接下来就可以向下面一样执行分页查询了。

SELECT *
FROM _tmp
WHERE OFFSET >= $offset
ORDER BY OFFSET
LIMIT $perpage;

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

热心网友 时间:2022-04-07 19:51

可以使用TOP分页啊
什么数据库都可以用的
例如:
select
top
5
*
from
a
where
a.id
not
in
(select
top
(5
*
1) id
from
b)
5
一页要获取的条数
1
是页数
1代表的是第二页

热心网友 时间:2022-04-07 21:26

select
*
from
数据表
order
by
id
limit
$num,$pages;
$num
//(当前页数-1)乘以每页条数
$pages//每页条数
这样就可以了
首页
$page=1
下一页
$page=$_GET['page']+1;
上一页
$page=$_GET['page']-1;
玉米仁子饭产自哪里 中国期货交易所的交易品种有哪些? 历史要怎么读,有啥诀窍 高中历史诀窍 年终会活动策划方案 深度解析:第一财经回放,探索财经新风向 逆水寒手游庄园怎么邀请好友同住 逆水寒手游 逆水寒不同区可以一起组队吗? 逆水寒手游 逆水寒怎么进入好友世界? 逆水寒手游 逆水寒怎么去别人的庄园? 使用puppeteer实现将htmll转成pdf 内卷时代下的前端技术-使用JavaScript在浏览器中生成PDF文档 【译】将HTML转为PDF的几种实现方案 变形金刚08动画怎么样 变形金刚08动画的问题 变形金刚08动画日语版剧情介绍 高分!换显卡nvidia控制面板被我卸了,重新安装显卡驱动后没了nvidia控... 我的nvidia控制面板被卸载了 怎么找回啊 卸载后 这个画面看着很奇怪_百 ... 李卓彬工作简历 林少明工作简历 广东工业职业技术学院怎么样 郑德涛任职简历 唐新桂个人简历 土地入股的定义 ups快递客服电话24小时 贷款记录在征信保留几年? 安徽徽商城有限公司公司简介 安徽省徽商集团新能源股份有限公司基本情况 安徽省徽商集团有限公司经营理念 2019哈尔滨煤气费怎么有税? 快手删除的作品如何恢复 体育理念体育理念 有关体育的格言和理念 什么是体育理念 万里挑一算彩礼还是见面礼 绿萝扦插多少天后发芽 绿萝扦插多久发芽 扦插绿萝多久发芽 炖牛排骨的做法和配料 网络诈骗定罪标准揭秘 “流水不争先”是什么意思? mc中钻石装备怎么做 为什么我的MC里的钻石块是这样的?我想要那种。是不是版本的问题?如果是... 带“偷儿”的诗句 “君不见巴丘古城如培塿”的出处是哪里 带“奈何”的诗句大全(229句) 里翁行()拼音版、注音及读音 带“不虑”的诗句 “鲁肃当年万人守”的出处是哪里 无尘防尘棚 mysql 数据库 分表后 怎么进行分页查询? mysql分页查询语句怎么写 Mysql 数据库怎么实现分页,要说的通俗一点儿 Mysql分页查询 mysql 数据量大的表如何做分页查询 qq聊天记录怎么才能彻底删除,为什么我的电手机上... MySql中查询语句实现分页功能 结合MySQL数据库,如何实现分页功能? mysql如何做分页查询? 考摩托车驾驶证一般是多少钱左右? 摩托车驾驶证怎么考和考试流程 现在摩托车驾照怎么考 摩托车驾驶证如何考? 考摩托车驾照都要走哪些程序 摩托车驾驶证怎么考? 摩托车驾照考试流程 如何考取摩托车驾驶证 考摩托车驾驶证怎么考 想考摩托车驾照大概走什么流程? 考摩托车驾照的流程 mysql里分页查询怎么写 mysql如何实现分页 mybatis+mysql怎么分页查询 mysql按条件分页查询的语句怎么写啊? mysql与oracle的分页查询语句? oracle和mysql分页查询问题 求教,mysql千万级数据多表查询做分页该如何优化 苹果12怎么显示手机电量 奥币等于多少人民币? 1奥币等于多少人民币 现在澳币对人民币是多少 澳币如何换算成人民币? 100澳币换算成人民币是多少钱? 5350奥币等于多少人民币? 1800澳币多少人民币 100000澳币是多少人民币 1300澳币多少人民币 36万奥币等于多少人民币? 22.9奥币换算人民币多少? 45000奥币是多少人民币?
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com