在 MySQL 中,limit X,Y 的查询中,X 值越大,那么查询速度也就越慢,例如以下示例:

  • limit 0,10:查询时间大概在 20 毫秒左右。
  • limit 1000000,10:查询时间可能是 15 秒左右(1秒等于 1000 毫秒),甚至更长时间。

所以,可以看出,limit 中 X 值越大,那么查询速度都越慢。

这个问题呢其实就是 MySQL 中典型的深度分页问题。那问题来了,为什么 limit 越往后查询越慢?如何优化查询速度呢?

为什么limit越来越慢?

在数据库查询中,当使用 LIMIT x, y 分页查询时,如果 x 值越大,查询速度可能会变慢。这主要是因为数据库需要扫描和跳过 x 条记录才能返回 y 条结果。随着 x 的增加,需要扫描和跳过的记录数也增加,从而导致性能下降。

例如 limit 1000000,10 需要扫描 1000010 行数据,然后丢掉前面的 1000000 行记录,所以查询速度就会很慢。

优化手段

对于 MySQL 深度分页比较典型的优化手段有以下两种:

  1. 起始 ID 定位法:使用最后查询的 ID 作为起始查询的 ID。
  2. 索引覆盖+子查询

1.起始ID定位法

起始 ID 定位法指的是 limit 查询时,指定起始 ID。而这个起始 ID 是上一次查询的最后一条 ID。例如上一次查询的最后一条数据的 ID 为 6800000,那我们就从 6800001 开始扫描表,直接跳过前面的 6800000 条数据,这样查询的效率就高了,具体实现 SQL 如下:

select name, age, gender
from person
where id > 6800000 -- 核心实现 SQL
order by id limit 10;

其中 id 字段为表的主键字段。

为什么起始ID查询效率高呢?

因此这种查询是以上一次查询的最后 ID 作为起始 ID 进行查询的,而上次的 ID 已经定位到具体的位置了,所以只需要遍历 B+ 树叶子节点的双向链表(主键索引的底层数据结构)就可以查询到后面的数据了,所以查询效率就比较高,如下图所示:

如果上次查询结果为 9,之后再查询时,只需要从 9 之后再遍历 N 条数据就能查询出结果了,所以效率就很高。

优缺点分析

这种查询方式,只适合一页一页的数据查询,例如手机 APP 中刷新闻时那种瀑布流方式。

但如果用户是跳着分页的,例如查询完第 1 页之后,直接查询第 250 页,那么这种实现方式就不行了。

2.索引覆盖+子查询

此时我们为了查询效率,可以使用索引覆盖加子查询的方式,具体实现如下。

假设,我们未优化前的 SQL 如下:

select name, age, gender
from person
order by createtime desc
limit 1000000,10;

在以上 SQL 中,createtime 字段创建了索引,但查询效率依然很慢,因为它要取出 100w 完整的数据,并需要读取大量的索引页,和进行频繁的回表查询,所以执行效率会很低。

此时,我们可以做以下优化:

SELECT p1.name, p1.age, p1.gender
FROM person p1
JOIN (
SELECT id FROM person ORDER BY createtime desc LIMIT 1000000, 10
) AS p2 ON p1.id = p2.id;

相比于优化前的 SQL,优化后的 SQL 将不需要频繁回表查询了,因为子查询中只查询主键 ID,这时可以使用索引覆盖来实现。那么子查询就可以先查询出一小部分主键 ID,再进行查询,这样就可以大大提升查询的效率了。

索引覆盖(Index Coverage)是一种数据库查询优化技术,它指的是在执行查询时,数据库引擎可以直接从索引中获取所有需要的数据,而不需要再回表(访问主键索引或者表中的实际数据行)来获取额外的信息。这种方式可以减少磁盘 I/O 操作,从而提高查询性能。

课后思考

你还知道哪些深度分页的优化手段呢?欢迎评论区留下你的答案。

面试官:limit 100w,10为什么慢?如何优化?的更多相关文章

  1. 面试官:JVM锁优化都优化了啥?

    从JDK1.6开始,JVM对锁进行了各种优化,目的就是为了在线程间更高效的共享数据和解决互斥同步的问题.从锁优化的话题开始,可以引申出很多考点面试题,比如锁优化的技术.各优化技术的细节.CAS实现原理 ...

  2. 「干货」面试官问我如何快速搜索10万个矩形?——我说RBush

    「干货」面试官问我如何快速搜索10万个矩形?--我说RBUSH 前言 亲爱的coder们,我又来了,一个喜欢图形的程序员‍,前几篇文章一直都在教大家怎么画地图.画折线图.画烟花,难道图形就是这样嘛,当 ...

  3. 面试官的七种武器:Java篇

    起源 自己经历过的面试也不少了,互联网的.外企的,都有.总结一下这些面试的经验,发现面试官问的问题其实不外乎几个大类,玩不出太多新鲜玩意的.细细想来,面试官拥有以下七种武器.恰似古龙先生笔下的武侠世界 ...

  4. 面试官:自己搭建过vue开发环境吗?

    开篇 前段时间,看到群里一些小伙伴面试的时候被面试官问到这类题目.平时大家开发vue项目的时候,相信大部分人都是使用 vue-cli脚手架生成的项目架构,然后 npm run install 安装依赖 ...

  5. 【Java8新特性】面试官问我:Java8中创建Stream流有哪几种方式?

    写在前面 先说点题外话:不少读者工作几年后,仍然在使用Java7之前版本的方法,对于Java8版本的新特性,甚至是Java7的新特性几乎没有接触过.真心想对这些读者说:你真的需要了解下Java8甚至以 ...

  6. 【高并发】面试官问我如何使用Nginx实现限流,我如此回答轻松拿到了Offer!

    写在前面 最近,有不少读者说看了我的文章后,学到了很多知识,其实我本人听到后是非常开心的,自己写的东西能够为大家带来帮助,确实是一件值得高兴的事情.最近,也有不少小伙伴,看了我的文章后,顺利拿到了大厂 ...

  7. MySQL 三万字精华总结 + 面试100 问,吊打面试官绰绰有余(收藏系列)

    写在之前:不建议那种上来就是各种面试题罗列,然后背书式的去记忆,对技术的提升帮助很小,对正经面试也没什么帮助,有点东西的面试官深挖下就懵逼了. 个人建议把面试题看作是费曼学习法中的回顾.简化的环节,准 ...

  8. MySQL优化篇(一),我可以和面试官多聊几句吗?——SQL优化流程与优化数据库对象

    我可以和面试官多聊几句吗?只是想偷点技能过来.MySQL优化篇(基于MySQL8.0测试验证),上部分:优化SQL语句.数据库对象,MyISAM表锁和InnoDB锁问题. MyISAM表锁和InnoD ...

  9. 面试官:MySQL一千万数据,怎么快速查询?

    前言 面试官:来说说,一千万的数据,你是怎么查询的? me:直接分页查询,使用limit分页. 面试官:有实操过吗? me:肯定有呀 此刻献上一首<凉凉> 也许有些人没遇过上千万数据量的表 ...

  10. Android开发面试经——6.常见面试官提问Android题②(更新中...)

    版权声明:本文为寻梦-finddreams原创文章,请关注:http://blog.csdn.net/finddreams 关注finddreams博客:http://blog.csdn.net/fi ...

随机推荐

  1. 文件系统(九):一文看懂yaffs2文件系统原理

    liwen01 2024.07.07 前言 yaffs 是专为nand flash 设计的一款文件系统,与jffs 类似,都是属于日志结构文件系统.与jffs 不同的是,yaffs 文件系统利用了na ...

  2. 【解决方案】智能UI自动化测试

    你的UI自动化追得上业务的变更和UI更迭吗?当今瞬息万变的时代,成千上万的App围绕着现代人生活的点点滴滴.为了满足用户的好的体验和时刻的新鲜感,这些App需要时刻保持变化,也给 UI自动化落地实施带 ...

  3. 自动化车间3D可视化设计思路

    自动化车间3D可视化设计思路 随着国内制造业企业的高速发展,再加上政策支持,高效的生产模式和先进的管理方式越来越受到企业重视.更多的企业将工业信息化技术进行广泛的应用,比如MES系统.数字孪生以及生产 ...

  4. thinkphp模型hasOne、hasMany、belongsTo详解

    在ThinkPHP框架中,hasOne.hasMany和belongsTo是用于定义模型间一对多(1:n).一对一(1:1)和多对一(n:1)关联关系的方法.以下是一些简单的示例来解释这些关系: 1. ...

  5. WSS SSL HTTPS之间的关系

    ssl: secure socket layer 安全套接层,简单来说是一种加密技术,通过它可以在通信的双方上建立一个安全的通信链路,因此数据交互的双方可以安全地通信,而不用担心数据被窃取:wss: ...

  6. oeasy教您玩转vim - 15 - # 行内查找

    行头行尾 回忆上节课内容 上次学了直接跳到开头和结尾 最重要的就是 ^.$ ^ 到开头 $ 到结尾 I 相当于^i A 相当于$a 查找帮助 还有什么呢? 还是继续在 motion 里面 ^ .$ 之 ...

  7. 前端说你的API接口太慢了,怎么办?

    当有千万条海量数据时,前端调取接口发现接口响应的太慢,前端这时让你优化一下接口,你说有几千万条数据,觉得自己尽力了,前端觉得你好菜,别急,读完这篇文章,让前端喊你一声:大佬,厉害!!! 常用的方法总结 ...

  8. 阶乘-n!_C语言实现

    n! // Code file created by C Code Develop #include "stdio.h" #include "stdlib.h" ...

  9. ComfyUI插件:ComfyUI Impact 节点(四)

    前言: 学习ComfyUI是一场持久战,而 ComfyUI Impact 是一个庞大的模块节点库,内置许多非常实用且强大的功能节点 ,例如检测器.细节强化器.预览桥.通配符.Hook.图片发送器.图片 ...

  10. systempath:Python开发者必备的文件与系统路径操作神器!

    systempath - 专业级的文件与系统路径操作库 English | 中文 systempath 是一个专为Python开发者设计的,高度专业化的文件与系统路径操作库.通过提供一套直观且功能强大 ...