在MySQL中使用LIMIT进行分页的方法,高效的mysql分页方法及原理

后天看一个水友说她的MySQL今后变的非常的慢。问什么动静时。说单表超越2个G的四个MyISAM。真垃圾的回答方式。

第生龙活虎看一下分页的基本原理:

不问可以预知回答:换多个无敌的服务器。换服务器很管用的:)

复制代码 代码如下:

……… 最后让取到慢查询:

mysql> explain SELECT * FROM message ORDER BY id DESC LIMIT 10000,
20G ***************** 1. row
************** id: 1 select_type: SIMPLE table: message
type: index possible_keys: NULL key: PRIMARY key_len: 4 ref: NULL
rows: 10020 Extra: 1 row in set (0.00 sec)

 SELECT * FROM pw_gbook WHERE uid='N' ORDER BY postdate DESC LIMIT N,N; SELECT * FROM pw_gbook WHERE uid='N' ORDER BY postdate DESC LIMIT N,N;

limit
10000,20的意思扫描满意条件的10020行,扔掉后边的10000行,重临最后的20行,难点就在此边,要是是limit
100000,100,须要扫描100100行,在一个高并发的使用里,每一次查询要求扫描超过10W行,品质肯定大优惠扣。文中还提到limit
n质量是没难点的,因为只扫描n行。

如:

文中提到生机勃勃种”clue”的做法,给翻页提供部分”线索”,比方依旧SELECT * FROM
message OXC90DER BY id
DESC,按id降序分页,每页20条,当前是第10页,当前页条约id最大的是9527,最小的是9500,借使我们只提供”上生龙活虎页”、”下黄金年代页”那样的跳转(不提供到第N页的跳转),那么在拍卖”上大器晚成页”的时候SQL语句能够是:

SELECT * FROM pw_gbook WHERE uid='48' ORDER BY postdate DESC LIMIT 1275480,20; SELECT * FROM pw_gbook WHERE uid='48' ORDER BY postdate DESC LIMIT 1275480,20;

复制代码 代码如下:

观看这几个语句小编都夜盲了。 小编那边大致说一下LIMIT的原理。这里以LIMIT
N,M为底子:LIMIT首先要找查N+M行,然后从N行处,取M行。那么这么的SQL对二回查询1275500多个操作应该是多少个值钱的开辟。对于LIMIT这类的优化,第贰个目的正是让N变的玩命的小大概不用。
怎么技艺使那么些N尽恐怕小吗。我们能做的其实正是用绝对的值,给分页两个提示。如现在大家看的是第5页,看完看想看第6页,第6页相似呈现是20条记下。我们就足以想到,以这几个事例为准:大家能够一定的是第6页的日值应小于第5页的,如若第5页的一丁点儿日值为:二零一零-11-4,那大家就能够用:

SELECT * FROM message WHERE id > 9527 ORDER BY id ASC LIMIT 20;

SELECT * FROM pw_gbook WHERE uid='48' and postdate'2009-11-1' ORDER BY postdate DESC LIMIT 20; SELECT * FROM pw_gbook WHERE uid='48' and postdate'2009-11-1' ORDER BY postdate DESC LIMIT 20;

拍卖”下大器晚成页”的时候SQL语句能够是:

诸有此类来查询第6页的源委。相通对于查看第4页的原委则第4页的内容为:

复制代码 代码如下:

 SELECT * FROM pw_gbook WHERE uid='48' and postdate'2009-11-3' ORDER BY postdate DESC LIMIT 20; SELECT * FROM pw_gbook WHERE uid='48' and postdate'2009-11-3' ORDER BY postdate DESC LIMIT 20;

SELECT * FROM message WHERE id < 9500 ORDER BY id DESC LIMIT 20;

那是贰个主干的沉思。接下来探讨一下怎么表现的主题材料。

任由翻多少页,每一趟查询只扫描20行。

再说一下这种职业的SQL怎么落到实处:对于分页的显示能够用多用类型。这里说两种常用的品类:

缺欠是一定要提供”上黄金时代页”、”下豆蔻年华页”的链接情势,不过大家的制品老板特别心仪”<上风流洒脱页
1 2 3 4 5 6 7 8 9 下黄金时代页>”那样的链接方式,咋做呢?

率先种:突显“” “”那类别型

假如LIMIT
m,n不可制止的话,要优化功用,唯有硬着头皮的让m小一下,大家扩张前面包车型大巴”clue”做法,如故SELECT
* FROM message OHavalDEENVISION BY id
DESC,按id降序分页,每页20条,当前是第10页,当前页条约id最大的是9527,最小的是9500,例如要跳到第8页,作者看的SQL语句能够这么写:

这种方式相对简便易行也就现身了大家看见这种SQL不思谋的写法。合理的做法:

复制代码 代码如下:

第一页:

SELECT * FROM message WHERE id > 9527 ORDER BY id ASC LIMIT 20,20;

SELECT * FROM pw_gbook WHERE uid='48' ORDER BY postdate DESC LIMIT 20; SELECT * FROM pw_gbook WHERE uid='48' ORDER BY postdate DESC LIMIT 20;

跳转到第13页:

其次页:依照第朝气蓬勃页的postdate进行查询如: SELECT * FROM pw_gbook
WHERE uid=’48’ and postdate’2009-11-3′ ORDER BY postdate DESC LIMIT 20;
SELECT * FROM pw_gbook WHERE uid=’48’ and postdate’2009-11-3′ ORDER BY
postdate DESC LIMIT 20;

复制代码 代码如下:

怎么说那个大致吗,这一个不设有跳页的主题材料。接下来这种就存在叁个跳页的标题了。

SELECT * FROM message WHERE id < 9500 ORDER BY id DESC LIMIT
40,20;

第二种:显示 “ 1,2,3,4,5…”

规律依旧一直以来,记录住当前页id的最大值和纤维值,总计跳转页面和当前页相对偏移,由于页面周边,这么些偏移量不会相当的大,那样的话m值相对超级小,大大收缩扫描的行数。其实守旧的limit
m,n,绝对的摇曳平素是第风姿罗曼蒂克页,那样的话越翻到后面,功用越差,而地点给出的法子就不曾这么的标题。

首先页: 照旧以率先页的章程得以完成:

当心SQL语句里面包车型客车ASC和DESC,若是是ASC收取来的结果,呈现的时候记得倒置一下。

 SELECT * FROM pw_gbook WHERE uid='48' ORDER BY postdate DESC LIMIT 20; SELECT * FROM pw_gbook WHERE uid='48' ORDER BY postdate DESC LIMIT 20;

已在60W数据总数的表中测量试验,效果万分肯定。

其次页:和原先同样。假设跳页,如从第二页跳到第5页,这里有二个次之页的纤维日期为:二〇〇八-11-3,第二到第5,差2页,每页20条记下,那么就足以用:

复制代码 代码如下:
mysql explain SELECT * FROM message ORDER BY id DESC LIMIT 10000, 20G
***************** 1. row **************
id:…

SELECT * FROM pw_gbook WHERE uid='48' and postdate'2009-11-3' ORDER BY postdate DESC LIMIT 40,20;SELECT * FROM pw_gbook WHERE uid='48' and postdate'2009-11-3' ORDER BY postdate DESC LIMIT 40,20;

看来这里了解为什么大型网址的分页不是弹指间标志出来完了,让都能点了吧。也不会给你四个框让您输入多个页跳过去了。若是跳的页面过多,也就存在N值过大的难题了。所以要想艺术必免。

第三种:显示 “1,2,3,4,5,…. 末页” 或是 “首页,100,101,102,103 末页”

这里有三个奇特的大器晚成地点:

别的页面包车型客车跳转的方面同样。这里就加三个末页,这里又分三种状态,若是知道最终大器晚成页是不怎么页,也就精通了前大器晚成页的微小日期,那样就能够用地方的秘籍查看最终风流罗曼蒂克页的剧情,另生机勃勃种,笔者就不亮堂最终是第几页,我就算想看看最终什么体统,那么就能够用:

SELECT * FROM pw_gbook WHERE uid='48' ORDER BY postdate ASC limit 20; SELECT * FROM pw_gbook WHERE uid='48' ORDER BY postdate ASC limit 20;

首页这里就不在说了。

现实怎么落到实处搞理解了,就能够做PHP代码的改善了。稍微改善一下,就能带给意料之外的功力。

此地只是二个通用的分页管理方法。分化的事务有相当大希望还应该有差异的法子处理。假若在尺度恐怕和状态能够考用:between
… and .. 带替代limit分页操作。

其二种办法: 大致的逻辑调换。

SELECT * FROM pw_gbook WHERE uid='48' ORDER BY postdate DESC LIMIT 1275480,20; SELECT * FROM pw_gbook WHERE uid='48' ORDER BY postdate DESC LIMIT 1275480,20;

转换成:

SELECT * FROM pw_gbook WHERE id1275480 and uid='48' ORDER BY postdate DESC LIMIT 20; SELECT * FROM pw_gbook WHERE id1275480 and uid='48' ORDER BY postdate DESC LIMIT 20;

发表评论

电子邮件地址不会被公开。 必填项已用*标注