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行。

缺点是只能提供”上一页”、”下一页”的链接形式,但是我们的产品经理非常喜欢”<上一页 1 2 3 45 6 7 8 9 下一页>”这样的链接方式,怎么办呢?

如果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分页算法的更多相关文章

  1. MySQL分页优化中的“INNER JOIN方式优化分页算法”到底在什么情况下会生效?

    本文出处:http://www.cnblogs.com/wy123/p/7003157.html 最近无意间看到一个MySQL分页优化的测试案例,并没有非常具体地说明测试场景的情况下,给出了一种经典的 ...

  2. MySQL、SqlServer、Oracle三大主流数据库分页查询 (MySQL分页不能用top,因为不支持)

    一. MySQL 数据库 分页查询MySQL数据库实现分页比较简单,提供了 LIMIT函数.一般只需要直接写到sql语句后面就行了.LIMIT子 句可以用来限制由SELECT语句返回过来的数据数量,它 ...

  3. MySQL分页查询的性能优化

    MySQL limit分页查询的性能优化 Mysql的分页查询十分简单,但是当数据量大的时候一般的分页就吃不消了. 传统分页查询:SELECT c1,c2,cn… FROM table LIMIT n ...

  4. Oracle、SQL Server、MySQL分页方法

    测试用例:查询TEST_TABLE表中TEST_COLUMN列的第10-20条数据 1,Oracle分页方法 SELECT A.* FROM ( SELECT ROWNUM ROWNO, B.* FR ...

  5. MySql 分页

    MySql 分页 由于最近项目需要,于是就简单写了个分页查询.总体而言MySql 分页机制较为简单.数据库方面只需要使用limit即可实现分页.前后台交互就直接用session传了值. 下面就写写具体 ...

  6. FluentData Mysql分页的一个BUG

    开发环境 FluentData3.0.VS.NET2010.Mysql5.0 问题描述 使用FluentData对一个表(记录数28)进行分页时,突然发现一个诡异的问题,第一页返回10条数据正常,第二 ...

  7. Mysql 分页语句Limit用法

    转载自:http://qimo601.iteye.com/blog/1634748 1.Mysql的limit用法 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用 ...

  8. php+mysql分页类的入门实例

    php+mysql分页类的简单代码 时间:2016-02-25 06:16:26来源:网络 导读:php+mysql分页类的简单代码,二个php分页类代码,对商品进行分页展示,当前页面数,每个页面展示 ...

  9. ASP的高效率的分页算法.net,php同样可以参考

    一般习惯使用的有两种分页算法,一是传统的ADO分页,二是SELECT TOP分页算法.对于小型数据表,比如一两万的数据量的表,我倾向使用ADO算法,对于大型的数据表,则必须采用后者的算法了. 先来说说 ...

随机推荐

  1. iOS、Xcode监测键盘的显示和隐藏变化,并获得键盘高度,改变tableView的frame和偏移

    <pre name="code" class="objc"><pre name="code" class="ob ...

  2. android AsyncTask介绍

    AsyncTask是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主 ...

  3. 【Swift】iOS开发历险记(二)

    前言 这个系列主要是一些开发中遇到的坑记录分享,有助于初学者跨过这些坑,攒够 7 条发一篇. 声明  欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.com 农民伯 ...

  4. 有氧运动 && 无氧运动

    有氧运动也叫做有氧代谢运动,是指人体在氧气充分供应的情况下进行的体育锻炼.有氧运动的好处是:可以提升氧气的摄取量,能更好地消耗体内多余的热量.也就是说,在运动过程中,人体吸入的氧气与需求相等,达到生理 ...

  5. Ignite安装配置——上篇

    Ignite介绍 Ignite 是SolarWinds公司开发的一款数据库性能监控.性能分析并提供优化解决方案的性能检测分析工具,Ignite配置简单.方便:它会收集实时会话数据.服务器资源使用情况, ...

  6. The process could not execute 'sp_repldone/sp_replcounters' on 'ServerName'

    昨天发现发布服务器S(SQL Server 2008 R2),出现大量如下错误 错误细节如下所示: Date :: PM :: PM) Source spid52 Message Replicatio ...

  7. SQL Server跨库查询

    方式一: 语句 SELECT * FROM 数据库A.dbo.表A a, 数据库B.dbo.表B b WHERE a.field=b.field "DBO"可以省略 如 SELEC ...

  8. Python 常用模块之time&datetime 和random

    本节大纲: 模块介绍 time &datetime模块 random 一.模块介绍: 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他 ...

  9. 解决Android Graphical Layout 界面效果不显示

    解决Android Graphical Layout 界面效果不显示 qq463431476

  10. linux下的守护进程daemon

    什么是守护进程?其实感觉守护进程并没有什么明确的定义,只是守护进程有一些特征,这是它需要遵循的. 守护进程的第一个特征是长时间在后台运行的程序,并且主要是为了提供某种服务,而为了能够让服务尽可能随时都 ...