PERCONA PERFORMANCE CONFERENCE 2009上,来自雅虎的几位工程师带来了一篇”Efficient Pagination Using MySQL“的报告,有很多亮点,本文是在原文基础上的进一步延伸。

首先看一下分页的基本原理:

mysql> explain SELECT * FROM message ORDER BY id DESC LIMIT 10000, 20\G

***************** 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)

limit 10000,20的意思扫描满足条件的10020行,扔掉前面的10000行,返回最后的20行,问题就在这里,如果是limit 100000,100,需要扫描100100行,在一个高并发的应用里,每次查询需要扫描超过10W行,性能肯定大打折扣。文中还提到limit n性能是没问题的,因为只扫描n行。

文中提到一种”clue”的做法,给翻页提供一些”线索”,比如还是SELECT * FROM message ORDER BY id DESC,按id降序分页,每页20条,当前是第10页,当前页条目id最大的是9527,最小的是9500,如果我们只提供”上一页”、”下一页”这样的跳转(不提供到第N页的跳转),那么在处理”上一页”的时候SQL语句可以是:

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

处理”下一页”的时候SQL语句可以是:

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

不管翻多少页,每次查询只扫描20行。

缺点是只能提供”上一页”、”下一页”的链接形式,但是我们的产品经理非常喜欢””这样的链接方式,怎么办呢?

如果LIMIT m,n不可避免的话,要优化效率,只有尽可能的让m小一下,我们扩展前面的”clue”做法,还是SELECT * FROM message ORDER BY id DESC,按id降序分页,每页20条,当前是第10页,当前页条目id最大的是9527,最小的是9500,比如要跳到第8页,我看的SQL语句可以这样写:

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

跳转到第13页:

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

原理还是一样,记录住当前页id的最大值和最小值,计算跳转页面和当前页相对偏移,由于页面相近,这个偏移量不会很大,这样的话m值相对较小,大大减少扫描的行数。其实传统的limit m,n,相对的偏移一直是第一页,这样的话越翻到后面,效率越差,而上面给出的方法就没有这样的问题。

注意SQL语句里面的ASC和DESC,如果是ASC取出来的结果,显示的时候记得倒置一下。

已在60W数据总量的表中测试,效果非常明显。

mysql 分页算法_MySQL高效的分页算法相关推荐

  1. mysql loop嵌套_MySQL中Nested-Loop Join算法小结

    数据库中JOIN操作的实现主要有三种:嵌套循环连接(Nested Loop Join),归并连接(Merge Join)和散列连接或者哈稀连接(Hash Join).其中嵌套循环连接又视情况又有两种变 ...

  2. mysql关联表分页查询_MySQL一对多分页查询-主表关联表条件查询问题

    文章目录 1 摘要 2 情景复现 2.1 数据模型 2.2 核心代码 2.3 测试数据 2.4 拓展一点 1 摘要 分页查询是后台项目中最常见的一种操作,在一对多(one to many)的关系表中, ...

  3. mysql中怎么分页查询_mysql怎样实现分页查询

    mysql分页查询的方法:1.用具体字段代替[*]:2.先查寻索引:3.使用[between - and],id必须是连续递增的:4.保留上一页记录所在id. mysql分页查询的方法: 简述通常在M ...

  4. mysql大量数据分页优化_mysql大量数据分页优化

    一般我们数据量大的时候,然后就需要进行分页,一般分页语句就是limit offset,rows.这种分页数据量小的时候是没啥影响的,一旦数据量越来越大随着offset的变大,性能就会越来越差.下面我们 ...

  5. mysql数据库写分页函数_mysql数据库写分页函数

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  6. JAVA实现的Johnson-trotter算法(高效的全排列算法)

    对集合S={a1,a2,...an},假设已经知道前n-1个元素的全排列{p1,p2,...,p(n-1)!},那么,这n个元素的全排列,可以这样生成 :用各种可能将an插入pi中,由此,得到集合S的 ...

  7. mysql limit 分页 优化_MYSQL分页limit速度太慢优化方法

    在mysql中limit可以实现快速分页,但是如果数据到了几百万时我们的limit必须优化才能有效的合理的实现分页了,否则可能卡死你的服务器哦. 当一个表数据有几百万的数据的时候成了问题! 如 * f ...

  8. mysql分页案例_MySQL优化案例系列-mysql分页优化

    通常,我们会采用ORDER BY LIMIT start, offset 的方式来进行分页查询.例如下面这个SQL: SELECT * FROM `t1` WHERE ftype=1 ORDER BY ...

  9. 分页及其管理、页面置换算法

    1.分页 大部分虚拟内存系统中都使用一种称为分页的技术. 在任何一台计算机上,程序引用了一组内存地址,由程序产生的这些地址称为虚拟地址,他们构成了一个虚拟地址空间. 在没有虚拟内存的计算机上,系统直接 ...

最新文章

  1. E-UTRA channel bandwidths per operating band (36.101)
  2. Python_面试题
  3. 问题 | Spare BA 中的Eigen运行错误
  4. ibator1.2.2
  5. mongodb创建普通用户并授权readWrite角色,并允许访问某一数据库
  6. linux分支结构,实验四 Shell脚本中的分支结构
  7. Android异常总结---type Status report message HTTP method GET is not supported by this URL
  8. HDFS副本放置策略
  9. mysql lex yacc脚本_终于成功配置lex和yacc的工具Parser Generator
  10. 一文带你了解JDK动态代理的原理
  11. Buck电路基础知识
  12. CHERRY樱桃机械键盘按键
  13. win7关于无线连接的服务器,win7网络连接受限
  14. 第十四周 项目2-用文件保存的学生名单
  15. 视频的编码与传输过程
  16. 你不得不了解的人工智能基础知识
  17. ffmpeg/ffplay 添加实时的时间水印
  18. 解析steam教育中的技术赋能
  19. 用Python写了一个不起床让你后悔的闹钟
  20. ContentProvider简结

热门文章

  1. 自定义多列排序:C++/Java实现
  2. win2003+IIS6+PHP5.3.8+MSSQL2008的安装配置
  3. sublime text3下BracketHighlighter的配置方法
  4. 宋体、文件-Ubuntu Linux中配置adb-by小雨
  5. datavideo切换台说明书_巴掌大三轴稳定器,稳过微云台,试试飞宇VLOGPocket2
  6. Will not attempt to authenticate using SASL | dubbo项目启动特别慢,拉取 zookeeper 服务日志打印特别慢
  7. 并发编程之多线程线程安全(下)
  8. Android 常用设计模式——观察者模式,单例模式,Builder模式,原型模式,命令模式
  9. android xml中设置水平虚线及竖直虚线
  10. python根据文件路径获取上级目录路径