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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: Mysql 我随手造200W条数据,给你们讲讲分页优化。

前言



【问诊一】


image.png


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


【问诊二】


image.png


正文



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


准备一张表:


image.png 


建个函数来造数据:


image.png


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


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


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


点击运行:


image.png


29秒造完,还可以。


 image.png


货到齐了,准备开搞:


image.pngimage.png


开始演练:


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


image.pngimage.png 


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


image.png


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


sql:


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

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


image.png


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


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


sql:


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


看看效果,用了3.765秒:


image.png


explain:


image.png

可以看到已经命中了索引 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



)


看下效果:


image.png


3.765秒 变成了 1.56秒 !!!

3.765秒 变成了 1.56秒 !!!

3.765秒 变成了 1.56秒 !!!


为啥?


explain看看:


image.png


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


回答 : 有。


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


方案2:使用最小条件值


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


上面分析这个sql的规则 :


image.png


看一下这个limit 120W,50的数据情况:


image.png


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


sql:


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


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


image.png


explain:


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


image.png服务端使用方案2:


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


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


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


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


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


配合前端使用方案2:


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


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

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

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5天前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
47 9
|
10天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
50 18
|
9天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
17 7
|
8天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化与慢查询优化:原理与实践
通过本文的介绍,希望您能够深入理解MySQL索引优化与慢查询优化的原理和实践方法,并在实际项目中灵活运用这些技术,提升数据库的整体性能。
28 5
|
9天前
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
38 6
|
22天前
|
关系型数据库 MySQL PHP
php实现一个简单的MySQL分页
通过本文的详细步骤和代码示例,我们实现了一个简单的PHP MySQL分页功能。主要步骤包括计算总记录数、设置分页参数、查询当前页的数据以及生成分页链接。这种分页方式适用于大多数Web应用,能够有效提升用户体验和页面响应速度。
24 4
|
20天前
|
SQL 关系型数据库 MySQL
mysql分页读取数据重复问题
在服务端开发中,与MySQL数据库进行数据交互时,常因数据量大、网络延迟等因素需分页读取数据。文章介绍了使用`limit`和`offset`参数实现分页的方法,并针对分页过程中可能出现的数据重复问题进行了详细分析,提出了利用时间戳或确保排序规则绝对性等解决方案。
|
26天前
|
关系型数据库 MySQL 数据库
GBase 数据库如何像MYSQL一样存放多行数据
GBase 数据库如何像MYSQL一样存放多行数据
|
分布式计算 关系型数据库 MySQL
E-Mapreduce如何处理RDS的数据
目前网站的一些业务数据存在了数据库中,这些数据往往需要做进一步的分析,如:需要跟一些日志数据关联分析,或者需要进行一些如机器学习的分析。在阿里云上,目前E-Mapreduce可以满足这类进一步分析的需求。
4979 0
|
13天前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
89 15