MySQL limit查询 百万级数据分页查询优化的两种方式

注 : 如解释错误的地方,请指出 会及时修改,谢谢 java学习笔记 思维导图版 码云仓库地址 https://gitee.com/vx202158/vx202158.git

一 生成测试数据

参考 文章 MySQL快速生成大量测试数据1000万

二 测试

1.创建索引

    建表时已经设置了 id 是自增主键 在innoDB存储引擎中 自增主键默认作为聚蔟索引

2.分页查询

2.1 通常方式

#测试 LIMIT  测试
select * from t limit 1900000,10

可以看到执行时间为0.36秒
在这里插入图片描述
对执行计划进行分析
在这里插入图片描述
可以看到 type 是 ALL 也就是最慢的全表扫描,操作了二百一十万行记录

2.2 优化方式一

思路

因为有主键索引 我们可以利用索引覆盖 首先查询 主键id 再利用 eq_ref

2.2.1 第一步 查询 id

因为有主键索引 我们可以利用索引覆盖 首先查询 主键id 再利用 eq_ref

select id from t order by id limit 1900000,10

在这里插入图片描述

分析SQL执行计划

SQL执行计划分析
在这里插入图片描述
可以看到 type 为 index 使用了主键索引 并且覆盖索引

2.2.1 第二步 eq_ref 关联子查询
    select t.* from t , ( select id from t order by id limit 1900000,10 ) t1 where t.id = t1.id

在这里插入图片描述
可以看到耗时为0.245s 优化了将近0.12s 数据量越大 优化时间越明细

分析SQL执行计划

接着分析SQL执行计划
在这里插入图片描述
可以看到 查询了两趟 (子查询导致) 第一趟查询了t表, 全索引扫描,使用了主键,以及覆盖索引
接着 对<derived2> 派生表 进行 全表扫描查询了10行记录 ,然后 对 关联表 t 进行 等值引用查询 </derived2>

2.2 优化方式二

思路

首先查询 我们进行分页的起始 主键id,然后用where 条件 range 查询 最后取 我们需要获取的记录数

2.2.1 第一步 查询 主键id
select id from t limit 1900000,1

在这里插入图片描述

分析SQL执行计划

SQL执行分析
在这里插入图片描述

操作t 表进行了 全索引扫描,使用了 主键索引,使用了覆盖索引

2.2.1 第二步 关联范围子查询
select * from t,(select id from t limit 1900000,1) t1 where t.id > t1.id LIMIT 0,10

在这里插入图片描述
可以看到耗时 仅需 0.19s 优化了0.17s

分析SQL执行计划

接着我们分析SQL执行计划
在这里插入图片描述

首先对 t 表进行了 全索引扫描操作,使用了 主键索引 ,并且覆盖索引
然后 对 派生表 <derived2> 进行了 system 操作(最快的系统属性操作)
在然后 对 t表进行范围查询,用到了主键索引 以及使用了where 条件</derived2>

总结

SQL操作速度快慢

system -> const  -> eq_ref -> ref -> range -> index -> all

优化limit分页查询方式列出了两种
第一种 先利用主键索引 查询 范围查询的 范围 主键id 然后进行关联子查询
查询类型为
eq_ref
index
all

第二种 先查出复合范围查询条件的id 的最小值 然后进行关联子查询 在分页
查询类型为
system
range
index

#2022春招##学习路径#
全部评论
之前学过一点点,不过后来没从事这个方向
点赞 回复 分享
发布于 2022-02-18 19:49
为什么直接查找不走索引
点赞 回复 分享
发布于 2023-09-23 14:19 北京

相关推荐

评论
点赞
1
分享
牛客网
牛客企业服务