SlideShare a Scribd company logo
高效的 MySQL 分页

April 29th, 2009 | by 超群.com | 知识共享署名-非商业性使用-相同方式共享,转载请保留
链接。

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


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


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)

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 idASC LIMIT 20;


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


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

不管翻多少页,每次查询只扫描 20 行。
缺点是只能提供”上一页”、”下一页”的链接形式,但是我们的产品经理非常喜欢”<上一页 1 2
3 4 5 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 idASC LIMIT 20,20;


 跳转到第 13 页:


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

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

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

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

Tags: MySQL, Performance

More Related Content

Similar to 高效的MySQL分页

IBM System X
IBM System XIBM System X
IBM System Xyangfan
 
互联网分布式系统架构分享-Qcon2011
互联网分布式系统架构分享-Qcon2011互联网分布式系统架构分享-Qcon2011
互联网分布式系统架构分享-Qcon2011Yiwei Ma
 
Qcon2011-54chen-互联网分步式构架分享
Qcon2011-54chen-互联网分步式构架分享Qcon2011-54chen-互联网分步式构架分享
Qcon2011-54chen-互联网分步式构架分享
zhen chen
 
Sql Server 高级技巧系列之三整体优化
Sql Server 高级技巧系列之三整体优化Sql Server 高级技巧系列之三整体优化
Sql Server 高级技巧系列之三整体优化向 翔
 
Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具
Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具
Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具HO-HSUN LIN
 
MySQL基础技能与原理——基本原理
MySQL基础技能与原理——基本原理MySQL基础技能与原理——基本原理
MySQL基础技能与原理——基本原理Michael Zhang
 
内部MySQL培训.3.基本原理
内部MySQL培训.3.基本原理内部MySQL培训.3.基本原理
内部MySQL培训.3.基本原理
Lixun Peng
 

Similar to 高效的MySQL分页 (7)

IBM System X
IBM System XIBM System X
IBM System X
 
互联网分布式系统架构分享-Qcon2011
互联网分布式系统架构分享-Qcon2011互联网分布式系统架构分享-Qcon2011
互联网分布式系统架构分享-Qcon2011
 
Qcon2011-54chen-互联网分步式构架分享
Qcon2011-54chen-互联网分步式构架分享Qcon2011-54chen-互联网分步式构架分享
Qcon2011-54chen-互联网分步式构架分享
 
Sql Server 高级技巧系列之三整体优化
Sql Server 高级技巧系列之三整体优化Sql Server 高级技巧系列之三整体优化
Sql Server 高级技巧系列之三整体优化
 
Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具
Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具
Microsoft CNTK, Cognitive Toolkit 微軟深度學習工具
 
MySQL基础技能与原理——基本原理
MySQL基础技能与原理——基本原理MySQL基础技能与原理——基本原理
MySQL基础技能与原理——基本原理
 
内部MySQL培训.3.基本原理
内部MySQL培训.3.基本原理内部MySQL培训.3.基本原理
内部MySQL培训.3.基本原理
 

More from wensheng wei

你会柔软地想起这个校园
你会柔软地想起这个校园你会柔软地想起这个校园
你会柔软地想起这个校园wensheng wei
 
几米语录(1)
几米语录(1)几米语录(1)
几米语录(1)wensheng wei
 
Installation of Subversion on Ubuntu,...
Installation of Subversion on Ubuntu,...Installation of Subversion on Ubuntu,...
Installation of Subversion on Ubuntu,...
wensheng wei
 
高级PHP应用程序漏洞审核技术
高级PHP应用程序漏洞审核技术高级PHP应用程序漏洞审核技术
高级PHP应用程序漏洞审核技术wensheng wei
 
存储过程编写经验和优化措施
存储过程编写经验和优化措施存储过程编写经验和优化措施
存储过程编写经验和优化措施wensheng wei
 
CentOS5 apache2 mysql5 php5 Zend
CentOS5 apache2 mysql5 php5 ZendCentOS5 apache2 mysql5 php5 Zend
CentOS5 apache2 mysql5 php5 Zendwensheng wei
 
Happiness is a Journey
Happiness is a JourneyHappiness is a Journey
Happiness is a Journey
wensheng wei
 
Java JNI 编程进阶
Java JNI 编程进阶     Java JNI 编程进阶
Java JNI 编程进阶 wensheng wei
 
Linux Shortcuts and Commands:
Linux Shortcuts and Commands:Linux Shortcuts and Commands:
Linux Shortcuts and Commands:
wensheng wei
 
Java正则表达式详解
Java正则表达式详解Java正则表达式详解
Java正则表达式详解wensheng wei
 
Linux Security Quick Reference Guide
Linux Security Quick Reference GuideLinux Security Quick Reference Guide
Linux Security Quick Reference Guide
wensheng wei
 
issue35 zh-CN
issue35 zh-CNissue35 zh-CN
issue35 zh-CN
wensheng wei
 
Android模拟器SD Card映像文件使用方法
Android模拟器SD Card映像文件使用方法Android模拟器SD Card映像文件使用方法
Android模拟器SD Card映像文件使用方法wensheng wei
 
如何硬盘安装ubuntu8.10
如何硬盘安装ubuntu8.10如何硬盘安装ubuntu8.10
如何硬盘安装ubuntu8.10wensheng wei
 
ubunturef
ubunturefubunturef
ubunturef
wensheng wei
 
数据库设计方法、规范与技巧
数据库设计方法、规范与技巧数据库设计方法、规范与技巧
数据库设计方法、规范与技巧wensheng wei
 
揭秘全球最大网站Facebook背后的那些软件
揭秘全球最大网站Facebook背后的那些软件揭秘全球最大网站Facebook背后的那些软件
揭秘全球最大网站Facebook背后的那些软件wensheng wei
 
mysql的字符串函数
mysql的字符串函数mysql的字符串函数
mysql的字符串函数wensheng wei
 

More from wensheng wei (20)

你会柔软地想起这个校园
你会柔软地想起这个校园你会柔软地想起这个校园
你会柔软地想起这个校园
 
几米语录(1)
几米语录(1)几米语录(1)
几米语录(1)
 
我的简历
我的简历我的简历
我的简历
 
Installation of Subversion on Ubuntu,...
Installation of Subversion on Ubuntu,...Installation of Subversion on Ubuntu,...
Installation of Subversion on Ubuntu,...
 
高级PHP应用程序漏洞审核技术
高级PHP应用程序漏洞审核技术高级PHP应用程序漏洞审核技术
高级PHP应用程序漏洞审核技术
 
存储过程编写经验和优化措施
存储过程编写经验和优化措施存储过程编写经验和优化措施
存储过程编写经验和优化措施
 
CentOS5 apache2 mysql5 php5 Zend
CentOS5 apache2 mysql5 php5 ZendCentOS5 apache2 mysql5 php5 Zend
CentOS5 apache2 mysql5 php5 Zend
 
Happiness is a Journey
Happiness is a JourneyHappiness is a Journey
Happiness is a Journey
 
Java JNI 编程进阶
Java JNI 编程进阶     Java JNI 编程进阶
Java JNI 编程进阶
 
Linux Shortcuts and Commands:
Linux Shortcuts and Commands:Linux Shortcuts and Commands:
Linux Shortcuts and Commands:
 
Java正则表达式详解
Java正则表达式详解Java正则表达式详解
Java正则表达式详解
 
Linux Security Quick Reference Guide
Linux Security Quick Reference GuideLinux Security Quick Reference Guide
Linux Security Quick Reference Guide
 
issue35 zh-CN
issue35 zh-CNissue35 zh-CN
issue35 zh-CN
 
Android模拟器SD Card映像文件使用方法
Android模拟器SD Card映像文件使用方法Android模拟器SD Card映像文件使用方法
Android模拟器SD Card映像文件使用方法
 
Subversion FAQ
Subversion FAQSubversion FAQ
Subversion FAQ
 
如何硬盘安装ubuntu8.10
如何硬盘安装ubuntu8.10如何硬盘安装ubuntu8.10
如何硬盘安装ubuntu8.10
 
ubunturef
ubunturefubunturef
ubunturef
 
数据库设计方法、规范与技巧
数据库设计方法、规范与技巧数据库设计方法、规范与技巧
数据库设计方法、规范与技巧
 
揭秘全球最大网站Facebook背后的那些软件
揭秘全球最大网站Facebook背后的那些软件揭秘全球最大网站Facebook背后的那些软件
揭秘全球最大网站Facebook背后的那些软件
 
mysql的字符串函数
mysql的字符串函数mysql的字符串函数
mysql的字符串函数
 

高效的MySQL分页

  • 1. 高效的 MySQL 分页 April 29th, 2009 | by 超群.com | 知识共享署名-非商业性使用-相同方式共享,转载请保留 链接。 PERCONA PERFORMANCE CONFERENCE 2009 上,来自雅虎的几位工程师带来了一 篇”Efficient Pagination Using MySQL“的报告,有很多亮点,本文是在原文基础上的进一步 延伸。 首先看一下分页的基本原理: 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) 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 idASC LIMIT 20; 处理”下一页”的时候 SQL 语句可以是: SELECT * FROM message WHERE id < 9500 ORDER BY idDESC LIMIT 20; 不管翻多少页,每次查询只扫描 20 行。
  • 2. 缺点是只能提供”上一页”、”下一页”的链接形式,但是我们的产品经理非常喜欢”<上一页 1 2 3 4 5 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 idASC LIMIT 20,20; 跳转到第 13 页: SELECT * FROM message WHERE id < 9500 ORDER BY idDESC LIMIT 40,20; 原理还是一样,记录住当前页 id 的最大值和最小值,计算跳转页面和当前页相对偏移,由于页 面相近,这个偏移量不会很大,这样的话 m 值相对较小,大大减少扫描的行数。其实传统的 limit m,n,相对的偏移一直是第一页,这样的话越翻到后面,效率越差,而上面给出的方法就 没有这样的问题。 注意 SQL 语句里面的 ASC 和 DESC,如果是 ASC 取出来的结果,显示的时候记得倒置一下。 已在 60W 数据总量的表中测试,效果非常明显。 Tags: MySQL, Performance