MySQL的分页技术总结

版权声明:此文章转载自ITeye。 web

如需转载请联系听云College团队成员阮小乙,邮箱:ruanqy#tingyun.comsql

方法1: 直接使用数据库提供的SQL语句

---语句样式: MySQL中,可用以下方法: SELECT * FROM 表名称 LIMIT M,N。数据库

---适应场景: 适用于数据量较少的状况(元组百/千级)。性能优化

---缘由/缺点: 全表扫描,速度会很慢且 有的数据库结果集返回不稳定(如某次返回1,2,3,另外的一次返回2,1,3)。Limit限制的是从结果集的M位置处取出N条输出,其他抛弃。服务器

方法2: 创建主键或惟一索引, 利用索引(假设每页10条)

---语句样式: MySQL中,可用以下方法:性能

SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) LIMIT M。

---适应场景: 适用于数据量多的状况(元组数上万)。字体

---缘由: 索引扫描,速度会很快。有朋友提出由于数据查询出来并非按照pk_id排序的,因此会有漏掉数据的状况,只能方法3。大数据

方法3: 基于索引再排序

---语句样式: MySQL中,可用以下方法: SELECT * FROM 表名称 WHERE id_pk > (pageNum*10) ORDER BY id_pk ASC LIMIT M。优化

---适应场景: 适用于数据量多的状况(元组数上万). 最好ORDER  BY后的列对象是主键或惟一因此,使得ORDERBY操做能利用索引被消除但结果集是稳定的(稳定的含义,参见方法1)。网站

---缘由: 索引扫描,速度会很快. 但MySQL的排序操做,只有ASC没有DESC(DESC是假的,将来会作真正的DESC,期待)。

方法4: 基于索引使用prepare(第一个问号表示pageNum,第二个?表示每页元组数)

---语句样式: MySQL中,可用以下方法:

PREPARE stmt_name FROM

---适应场景: 大数据量。

---缘由: 索引扫描,速度会很快. prepare语句又比通常的查询语句快一点。

方法5:利用MySQL支持ORDER操做能够利用索引快速定位部分元组,避免全表扫描

---好比: 读第1000到1019行元组(pk是主键/惟一键)。

---SELECT * FROM your_table WHERE pk>=1000 ORDER BY pk ASC LIMIT 0,20。

方法6: 利用"子查询/链接+索引"快速定位元组的位置,而后再读取元组. 道理同方法5

---如(id是主键/惟一键,蓝色字体时变量):

利用子查询示例:

SELECT * FROM your_table WHERE id <= (SELECT id FROM your_table ORDERBY id desc LIMIT ($page-1)*$pagesize ORDER BY id descLIMIT $pagesize

利用链接示例:

SELECT * FROM your_table AS t1JOIN (SELECT id FROM your_table ORDER BYid desc LIMIT ($page-1)*$pagesize AS t2WHEREt1.id <= t2.id ORDER BY t1.id desc LIMIT $pagesize;

方法7: 存储过程类(最好融合上述方法5/6)

---语句样式: 再也不给出

---适应场景: 大数据量.  做者推荐的方法

---缘由: 把操做封装在服务器,相对更快一些。

方法8: 反面方法

---网上有人写使用 SQL_CALC_FOUND_ROWS。没有道理,勿模仿 。

基本上,能够推广到全部数据库,道理是同样的。但方法5未必能推广到其余数据库,推广的前提是,其余数据库支持ORDER BY操做能够利用索引直接完成排序。

想阅读更多技术文章,请访问听云技术博客,访问听云官方网站感觉更多应用性能优化魔力。