当前位置: 首页 > news >正文

Mysql 我随手造200W条数据,给你们讲讲分页优化。

前言

【问诊一】

MySql 索引失效、回表解析 【陈先生们,先看这篇】

【问诊二】

正文

话不多说,先当场整点货,搞个200w条数据:

准备一张表:

 建个函数来造数据:
 

 估计很多初学者可能很少写这些,没关系,可以一起动手试着玩玩:

CREATE DEFINER=`mytoor`@`%` FUNCTION `JcTestData`() RETURNS int(11)
BEGIN                                
    DECLARE num INT DEFAULT 2000000;         
    DECLARE i INT DEFAULT 0; 
    
    WHILE i < num DO             
    INSERT INTO test_order(`platform_sn`,`third_sn`,`type`,`create_time`) 
         VALUES(CONCAT('SN',i),UUID(),1,now());
        SET i =  i + 1;
    END WHILE;        
    RETURN i;
END

简单说一嘴,看明白的可以无视这个(还是那句话学习,是先知后知而已): 

 点击运行:

29秒造完,还可以。 

货到齐了,准备开搞:

开始演练:


先给type加个索引,模拟一下真实查询场景: 

 再把几条数据的type数据稍微改一下,:

先按照正常的场景分页查询 limit 0,50:

 

sql:
 

select * FROM test_order  where type=1  limit 0,50;

可以看到查询 limit 0,50  速度是很快的,0.022秒: 

我们接下来模拟成查询N页之后的数据 limit  1200000,50:

120W 条后,偏移 50条数据,roll出来

sql:

select * FROM test_order  where type=1  limit 1200000,50;

看看效果,用了3.765秒:


explain:

 可以看到已经命中了索引 index_type ,但是还是比较慢,为什么呢?

慢的原因 ① 

① 索引 index_type 是非聚簇索引, 而我们查询的语句 是select * ,包含了其他字段。

通过非聚簇索引 index_type  roll出来的数据列,只有type 和 id ,那么为了拿其他字段,

就会通过先取聚簇索引 id ,再根据id 拿出所有列值,这也就是回表操作。 

慢的原因 ②

limit 第一个数,第二个数

limit 的roll数据规则是什么 ? 

是确定sql的符合条件的数据,
根据 limit的 第一个数 + 第二个数,先计算出总共需要扫描拿到的数据总量是多少,
再去从头开始遍历到第一个数的数据行,开始丢到返回集,
丢多少条呢? 第二个数决定着丢多少条。

limit 示例讲解

也就是limit 0,50 :

计算 0+ 50  =50 , 拿出符合条件的50条 , 从头开始匹对第一个数  0,OK,从0开始就可以把数据丢到返回集。

丢多少?  第二个数是 50,所以会一条条丢,丢50条 ,最后返回数据。

那么如果是我们文章里面执行的  limit 1200000,50 :


120w+50  ....

意味着为了拿50条数据,需要扫描出 1200050 条数据,然后开始迅速得检索第一个数是120W,开始丢掉前面120W条没有意义的数据,然后确定第二个数是50,开始整50条数据丢到返回集里面,最后返回数据。

那么既然知道了这个情况, 我们可以开始玩优化操作。

方案1 :

针对回表方面做优化

如果我们能拿到我们知道返回数据的 id 集,作为条件,这样通过命中非聚簇索引type的时候,直接就能拿到id,这样通过id拿数据列,这样就方便了。

sql:
 

select * FROM test_order  where id in

(


select id from (select id FROM test_order  where type=1 limit 1200000,50) child


看下效果:
 

3.765秒 变成了 1.56秒 !!!

3.765秒 变成了 1.56秒 !!!

3.765秒 变成了 1.56秒 !!!

为啥? 

explain看看:

这种情形已经是快了很多了, 但是还有没有操作空间?

回答 : 有。

可以看到当前的优化sql ,其实 还是涉及到了 limit 1200000,50 ,这也就是主要耗费时间的地方。

方案2:使用最小条件值

分页查询避免跳页查询, 我们把上一页的id,作为下一页的起始条件。

上面分析这个sql的规则 :
 看一下这个limit 120W,50的数据情况:

 如果我们加上 条件  id >=1200008  , 是不是就非常nice了 。

sql:

select * FROM test_order  where type=1 and id >=1200008 limit 50;

看看效果,0.022秒,就跟直接 limit 0,50 一样了效率了:


 explain:

都中了主键索引了,key:PRINARY

服务端使用方案2:

这种情况,如果是我们代码里面去使用,只需要在操作大批量数据的时候,将上一批数据的最后一条数据的id拿出来。

给到下一批筛选数据,作为最小ID的 条件即可。

其实也就是之前我写过一篇文章留下来的分页优化操作空间:


Springboot 手动分页查询,分批批量插入数据_小目标青年的博客-CSDN博客

可以在这篇基础上,加上 上一批次的最小ID作为条件,效率翻倍!

配合前端使用方案2:

给大家看一个现成的大系统的一个触发机制调用图:

 随着滑动,自动加载下一页数据, 起始也就是把上一页的最小ID值(可以传其他条件值也可以)透传到下一页。这种其实我们产品体验上的滑动加载,瀑布流形式。

好了,该篇就到这,关注我,点赞,收藏(给我知道你们在,给我知道你们懂我)。

相关文章:

  • 【云原生】风云暗涌的时代,DBA们的利刃出鞘了
  • 以后面试官问你 为啥不建议使用Select *,请你大声回答他!
  • Springboot 导入导出Excel ,一对多关系,复合表格、合并单元格数据
  • 怎么清晰地理解、表达 IaaS 、 PaaS 、 SaaS ?
  • UML类图的六大关系,最佳学习理解方式
  • Springboot 整合 Socket 实战案例 ,实现 单点发送、广播群发,1对1,1对多
  • Springboot Mybatis 、JPA 调用存储过程,实战教程
  • 写代码的七八九十宗罪,多图、胆小慎入!
  • Springboot byte[] 转 MultipartFile ,InputStream 转 MultipartFile
  • Springboot 最细节全面的接口传参接参介绍,总有你喜欢的一种方式
  • Springboot 整合RabbitMq ,用心看完这一篇就够了
  • 用过Apifox这个API接口工具后,确实感觉postman有点鸡肋......
  • ClickHouse 挺快,esProc SPL 更快
  • 苹果6sp内存可以扩展吗_饮用苹果醋可以减肥吗?
  • tcpdump抓两个网卡的包_Kubernetes 疑难杂症排查分享:神秘的溢出与丢包
  • __proto__ 和 prototype的关系
  • 【391天】每日项目总结系列128(2018.03.03)
  • 【5+】跨webview多页面 触发事件(二)
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • Protobuf3语言指南
  • 分布式事物理论与实践
  • 关于extract.autodesk.io的一些说明
  • 三分钟教你同步 Visual Studio Code 设置
  • ​马来语翻译中文去哪比较好?
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #《AI中文版》V3 第 1 章 概述
  • #if #elif #endif
  • #Z0458. 树的中心2
  • #微信小程序(布局、渲染层基础知识)
  • (7)STL算法之交换赋值
  • (十六)一篇文章学会Java的常用API
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .sdf和.msp文件读取
  • /run/containerd/containerd.sock connect: connection refused
  • /var/lib/dpkg/lock 锁定问题
  • @converter 只能用mysql吗_python-MySQLConverter对象没有mysql-connector属性’...
  • @DependsOn:解析 Spring 中的依赖关系之艺术
  • @Repository 注解
  • [ 云计算 | AWS 实践 ] 基于 Amazon S3 协议搭建个人云存储服务
  • []Telit UC864E 拨号上网
  • [30期] 我的学习方法
  • [AutoSar]BSW_Memory_Stack_004 创建一个简单NV block并调试
  • [CodeForces-759D]Bacterial Melee
  • [codevs 1515]跳 【解题报告】
  • [Eclipse] 详细设置护眼背景色和字体颜色并导出
  • [Enterprise Library]调用Enterprise Library时出现的错误事件之关闭办法
  • [HackMyVM]靶场Crossbow
  • [iOS]把16进制(#871f78)颜色转换UIColor
  • [LeetCode周赛复盘] 第 312 场周赛20220925
  • [MAC OS] 常用工具
  • [Oh My C++ Diary]用cout输出时后endl的使用
  • [POJ2411]Mondriaan's Dream