SQL优化是要看执行计划分析,并做基准测试的。


前言

MySQL官方关于LIMIT子句的优化建议在之前的文章中写过,链接如下:

8.2.19 LIMIT查询优化.note

【MySQL 8翻译】8.2.19 LIMIT查询优化_影三人的博客-CSDN博客

对网上经常讨论的对分页查询时LIMIT偏移量过大的优化,思路大体上没什么问题,但额外增加了很多先决条件,比如需要提供上页最后一条记录的主键(或其他唯一键)值,且该值单调递增(不必连续)。这些文章的源头大多是《高性能MySQL》这本书。


正文

“需求”驱动“应用”,“应用”驱动“设计”。这种问题在常见应用中应该很少遇到,如果是前端用户行为,谁会去翻看一万多页,一般看10页以上就觉得烦了;除了用户行为,那我猜测就只能是爬虫或者是OLAP分析类应用了。

总体上,偏移量非常大的分页查询的优化方案分两类:

1、页面中限制分页数量

前端只限制返回一定量的分页,超过则不予展示

2、优化偏移量的性能,又分为:

2.1 覆盖索引 + JOIN

先利用分页查询找到所需记录的主键(比如ID)生成派生表,再通过主键作为连接条件与原表连接(嵌套循环连接)。

2.2 预先准备某些东西

2.2.1 预先准备“位置”字段,转换为已知位置的查询

需要一个存储位置信息的字段,该字段单调连续递增且建有索引,该值通常需要预先计算得到。MySQL通过索引范围扫描获得相应结果。

mysql> select * from employee where position between 10050 and 10099;

2.2.2 预先准备上页的最后一条记录的唯一键的值作为“书签”,使用“书签”

假设上页最后一条记录的主键ID(或其他唯一键)的值为10049,则查询本页数据记录可以执行:

mysql> select * from employee where id > 10049 limit 50;

同时,记录新的“书签”为10099(即10049+50)。

注意,某些情况下所需数据的ID并非连续的,此时不能简单进行加减运算,需要读取最后一条记录的“书签”值。

2.2.3 《高性能MySQL》中的其他优化方法

包括使用预先计算的汇总表,或者关联到一个只包含需要做排序的数据列和主键列的冗余表,

2.3 使用Sphinx优化一些搜索操作

该方案对于MySQL 8等新版本MySQL已不具优势,某些情况下对于旧版本MySQL具备一定优势:

  • 使用max_matches选项,以每个服务器和每个查询为基础,可控制类似“sort_buffer"的大小。MySQL 8中sort_buffer_size表示其最大阈值,每个会话会获得一个很小的初始大小sort_buffer,然后MySQL会根据实际使用情况动态改变。
  • 顺序I/O读取磁盘,而不是旧版本MySQL中的半随机方式。MySQL 8中使用 Disk-Sweep Multi-Range Read (MRR)技术来优化。

当表很大且没有存储在存储引擎缓存内时,使用次级索引上的范围扫描读取行会导致对基表的大量随机磁盘访问。通过MRR可以先缓存次级索引记录再按行ID进行排序,最终将大量随机磁盘访问转化为一次或多次顺序磁盘访问。该设计思路类似于Change Buffer的设计思路。详见MySQL :: MySQL 8.0 Reference Manual :: 8.2.1.11 Multi-Range Read Optimization


测试

详细内容因格式与篇幅问题无法展示,烦请移步至我分享的有道云笔记偏移量大的分页查询LIMIT子句的优化方法查看。

虽从上面代码块可以看出,使用"书签"并使用ID排序的SQL-B2优于不使用“书签”的SQL-JOIN,使用"书签"并使用ID排序的SQL-B2很可能是最优解,但算上应用程序获取“书签”的时间,两者孰优孰劣并不清晰,需做基准测试并依据具体情况具体分析。

我认为这种比较就是不公平的,没有可比性。前者额外增加了已知条件,如果允许这种“作弊”,那为什么只缓存一页,而不是执行一次SQL一次缓存100页,前端显示的分页由应用程序的缓存提供,在查101页时再触发一次对数据库的查询?这样显然更优,同样,类似的额外增加的优化手段还有很多,每增加新的条件,总会比没增加前更优,但同样也会使系统变得越来越复杂臃肿。

结论

1、使用“书签”可能是最优的优化方案,但需要额外成本和限制。

2、在获取“书签”的成本较高时,使用JOIN派生表的方案也可能是最优的优化方案,没有额外成本和限制,适用几乎所有场景。


后记

做这个测试、写这篇文章的最初目的是为了怼该UP主,当看到他把倒序排序的“书签”条件写成“ID > XXX”(正确的应该用小于"<"),而且不用ID排序反用CREATE_TIME排序时我就想怼了,后面又看到IN形式的半连接查询中包含LIMIT,我就更想怼了。而后与他评论区battle的过程中,我说应用缓存(后端或前端),他硬是理解成Redis缓存,后面发现他的认知中只知道Redis能缓存。。。还说MongoDB现在多垃圾,垃圾人家DB-Engines这两年评分排名疯狂上涨?真服了这些一瓶子不满半瓶子晃荡的老六了!成天搁这误人子弟!他最多是个给大厂做外包的程序员,要真是大厂的,除非哪个大厂眼瞎!搞Java的不好好搞Java,成天好为人师给人家讲解数据库,你说好不好笑!

【MySQL Tips】偏移量大的分页查询LIMIT子句的优化方法相关推荐

  1. 大数据分页查询 or 导出 慢sql治理

    大数据分页查询 or 导出 慢sql治理 背景 缺陷 要求 优化方案 适用场景 方案优点 方案缺点 时间拆分如处理分页查询问题 方案说明 使用说明 分页查询工具 时间拆分工具 背景 当前日增数据量将近 ...

  2. MySQL分页查询速度慢的优化

    数据数量足够大的分页查询会变得慢,这个时候我们就需要进行优化. 优化的方法也有很多,下面简述一下我用过的一些方法. 表名:order_history 描述:某个业务的订单历史表 主要字段:unsign ...

  3. DevExpress ChartControl大数据加载时有哪些性能优化方法

    DevExpress ChartControl加载大数据量数据时的性能优化方法有哪些? 关于图表优化,可从以下几个方面解决: 1.关闭不需要的可视化的元素(如LineMarkers, Labels等) ...

  4. mysql临时表如何分页查询慢_数据量很大,分页查询很慢,怎么优化?

    作者:悠悠i,来源: http://uee.me/aVSnD 当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时需要使用分页查询.对于数据库分 ...

  5. MySQL优化:数据量很大,分页查询很慢,有什么优化方案?

    准备工作 一般分页查询 使用子查询优化 使用 id 限定优化 使用临时表优化 关于数据表的id说明 当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明 ...

  6. mysql临时表如何分页查询慢_面试官扎心一问:数据量很大,分页查询很慢,有什么优化方案?...

    准备工作 一般分页查询 使用子查询优化 使用 id 限定优化 使用临时表优化 关于数据表的id说明 当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明 ...

  7. mysql 分页查询分析_mysql 大表分页查询测试分析优化

    http://blog.csdn.net/xluren/article/details/32746183 http://www.cnblogs.com/kupig/archive/2011/10/19 ...

  8. MySQL数据库分页查询limit

    1. 分页查询介绍 当数据特别多,一页显示不完,需要一页一页的进行显示,这就是分页查询. 2. 分页查询语法 select * from 表名 limit start,count 说明: limit是 ...

  9. java中的分页 效率考虑_面试官:数据量很大,分页查询很慢,有什么优化方案?...

    当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时需要使用分页查询.对于数据库分页查询,也有很多种方法和优化的点. 下面简单说一下我知道的一些 ...

最新文章

  1. 用linux创建raid5,使用mdadm快速创建RAID5....(比赛后的小结!)
  2. 再说spring比较重,臃肿的看此文!!!!!
  3. 火热的激情、严密的计划成就双冠梦想——我的项管经验(转载)
  4. 【直播回放】2小时全面剖析图像分类任务,学习CV必知
  5. SharePoint 2013常用开发工具分享
  6. 三星note2+android8.0,放大版Note2 三星Galaxy Note8.0
  7. 小数乘分数怎么算过程_GMAT分数到底怎么算?我该做对多少题GMAT才能达到700+?...
  8. Cloud for Customer里权限控制Business Role和Access context的截图
  9. mysql schema table_关于数据库中table与schema的区别详解
  10. C++:52---多重继承
  11. [转]VisualStudio如何组织解决方案的目录结构
  12. 一位跟我一样疑惑的同学~
  13. 你以为熬个3年工作经验就是Java高级开发了?
  14. ActionScript 与后台交互 RemoteObject
  15. 最小生成树-Prim算法的Python实现
  16. OSPF的多域配置-要点总结
  17. C#学习笔记29——c#使用word、excel、pdf
  18. 原神3.2私人服务器搭建
  19. 软考之系统架构师考试经验分享
  20. 移动端h5页面监听手机横屏

热门文章

  1. float和absolute的区别
  2. python语言基础知识
  3. 第09期精品旅游网站
  4. 2016中国VR行业预测研究报告
  5. 动态分析和静态分析最主要的区别是什么?
  6. Emscripten 单词_【英语高考】高中人教版英语 必修15单词朗读汇总
  7. 金庸笔下的“十大名师”
  8. Linux和Windows共享文件夹:/mnt目录下没有/hgfs的解决办法
  9. 中式快餐上市潮来袭?老乡鸡、老娘舅启动辅导,前者刚被通报责令改正
  10. 【面试技巧】成功的面试自我介绍三步骤