`
webcode
  • 浏览: 5925620 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

教你优化MySQL查询语句,实现高效分页,轻松响应60W请求

 
阅读更多
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 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数据总量的表中测试,效果非常明显。

分享到:
评论

相关推荐

    MySQL10.zip

    能够根据数据需求编写对应的SQL语句(查询、更新、删除、插入,条件、排序、分组、分页、子查询等),能够使用数据库编程完成对数据库的操作 理解PYTHON解决语法规则及其开发中的应用场景 理解web框架中的处理流程...

    python入门到高级全栈工程师培训 第3期 附课件代码

    07 Django请求生命周期之响应内容 08 学员管理示例:数据库设计 09 学员管理示例:班级管理 10 学员管理示例:学员管理 第55章 01 Django的ORM基本操作补充之概要 02 Django的ORM基本操作补充之一对多 03 学员管理...

    ASP.NET3.5从入门到精通

    13.1.2 Response 请求响应对象 13.1.3 Application 状态对象 13.1.4 Session 状态对象 13.1.5 Server 服务对象 第一篇窗口与界面编程 17 13.1.6 Cookie 状态对象 13.1.7 Cache 缓存对象 13.1.8 Global.asax 配置 ...

    ASPNET35开发大全第一章

    13.1.2 Response请求响应对象 13.1.3 Application状态对象 13.1.4 Session状态对象 13.1.5 Server服务对象 13.1.6 Cookie状态对象 13.1.7 Cache缓存对象 13.1.8 Global.asax配置 13.2 ASP.NET应用程序配置 13.2.1 ...

    asp.net知识库

    ASP.NET2.0中themes、Skins轻松实现网站换肤! ASP.NET 2.0 中的代码隐藏和编译 ASP.NET 2.0 Language Swithcer and Theme Swicher 多语言转换和多样式主题转换 ASP.NET2.0 ObjectDataSource的使用详解(1) ASP.NET...

    Java常见面试题208道.docx

    178.如何做 mysql 的性能优化? 十八、Redis 179.redis 是什么?都有哪些使用场景? 180.redis 有哪些功能? 181.redis 和 memecache 有什么区别? 182.redis 为什么是单线程的? 183.什么是缓存穿透?怎么解决? ...

    ASP.NET 3.5 开发大全11-15

    13.1.2 Response请求响应对象 13.1.3 Application状态对象 13.1.4 Session状态对象 13.1.5 Server服务对象 13.1.6 Cookie状态对象 13.1.7 Cache缓存对象 13.1.8 Global.asax配置 13.2 ASP.NET应用程序配置 13.2.1 ...

    ASP.NET 3.5 开发大全

    13.1.2 Response请求响应对象 13.1.3 Application状态对象 13.1.4 Session状态对象 13.1.5 Server服务对象 13.1.6 Cookie状态对象 13.1.7 Cache缓存对象 13.1.8 Global.asax配置 13.2 ASP.NET应用程序配置 13.2.1 ...

    ASP.NET 3.5 开发大全1-5

    13.1.2 Response请求响应对象 13.1.3 Application状态对象 13.1.4 Session状态对象 13.1.5 Server服务对象 13.1.6 Cookie状态对象 13.1.7 Cache缓存对象 13.1.8 Global.asax配置 13.2 ASP.NET应用程序配置 13.2.1 ...

    ASP.NET 3.5 开发大全word课件

    13.1.2 Response请求响应对象 13.1.3 Application状态对象 13.1.4 Session状态对象 13.1.5 Server服务对象 13.1.6 Cookie状态对象 13.1.7 Cache缓存对象 13.1.8 Global.asax配置 13.2 ASP.NET应用程序配置 13.2.1 ...

    乐优商城.xmind

    name 命名为aa,然后sql语句....where s_name= #{aa} 中就可以根据aa得到参数值 修改 回显 Controller @PathVariable("bid") 通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中...

    php网络开发完全手册

    4.2.1 获得日期时间信息的函数getdate 60 4.2.2 获得当前时间的函数 4.2.2 gettimeofday 61 4.2.3 日期验证函数checkdate 61 4.2.4 格式化本地时间日期的函数date 62 4.2.5 获得本地化时间戳的函数mktime 64 4.2.6 ...

    (全)传智播客PHP就业班视频完整课程

    8-22 1.break语句 continue语句 常量 8-22 2.函数基本概念 函数快速入门 8-22 3.函数使用函数调用初步理解 8-22 4.函数调用深入理解 函数使用注意事项① 8-22 5.函数使用注意事项② 函数作业布 8-23 1.函数再回顾 ...

    史上最全韩顺平传智播客PHP就业班视频,10月份全集

    8-22 1.break语句 continue语句 常量 8-22 2.函数基本概念 函数快速入门 8-22 3.函数使用函数调用初步理解 8-22 4.函数调用深入理解 函数使用注意事项① 8-22 5.函数使用注意事项② 函数作业布 8-23 1.函数再回顾 ...

    史上最全传智播客PHP就业班视频课,8月份视频

    8-22 1.break语句 continue语句 常量 8-22 2.函数基本概念 函数快速入门 8-22 3.函数使用函数调用初步理解 8-22 4.函数调用深入理解 函数使用注意事项① 8-22 5.函数使用注意事项② 函数作业布 8-23 1.函数再回顾 ...

    韩顺平PHP JS JQUERY 所有视频下载种子 货真价实

    8-22 1.break语句 continue语句 常量 8-22 2.函数基本概念 函数快速入门 8-22 3.函数使用函数调用初步理解 8-22 4.函数调用深入理解 函数使用注意事项① 8-22 5.函数使用注意事项② 函数作业布 8-23 1.函数再回顾 ...

    史上最全韩顺平传智播客PHP就业班视频,9月份全集

    8-22 1.break语句 continue语句 常量 8-22 2.函数基本概念 函数快速入门 8-22 3.函数使用函数调用初步理解 8-22 4.函数调用深入理解 函数使用注意事项① 8-22 5.函数使用注意事项② 函数作业布 8-23 1.函数再回顾 ...

    老男孩第三期Python全栈开发视频教程 零基础系统学习Python开发视频+资料

    ├─(105) 09 python全栈3 day54 Django请求生命周期之响应内容(一).avi ├─(106) 10 python全栈3 day54 Django请求生命周期之响应内容(二).avi ├─(107) 11 python全栈3 day54 学员管理示例:数据库设计.avi ...

    JAVA上百实例源码以及开源项目

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    JAVA上百实例源码以及开源项目源代码

    5个目标文件,演示Address EJB的实现 ,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

Global site tag (gtag.js) - Google Analytics