200w数据分析+实测深入理解sql索引使用

mysql 深入理解索引使用

简单聊聊下面这条简单sql 的执行与优化
SQL: select * from user where age>20 and weight<70 order by add_time limit 500000 100;

环境 mysql 5.6 2核2g 阿里云服务器
user表:age,name,weight add_time desc 200w数据 ,单条数据0.5k左右
age>20 数据量100w
weight<70 数据量110w
age>20 && weight <70 数据量80w

sql可能执行路径理论分析(分析只是理论,实际情况根据后面的测试判断):
1: 无索引情况
执行流程:全表扫描 就是加载整个表的数据 根据条件逐条判断是否符合,最后将符合条件的数据根据时间排序取100条
时间消耗:读取整个表+扫描200w数据+排序80w数据

2:添加单列索引 age 或者weight
执行流程:选择age 或者weiht索引 从索引去掉不符合的数据剩下的数据回表查找另一个字段后筛选 然后根据时间排序 取出100条数据
时间消耗:回表100w数据+排序100w数据

3使用 add_time 索引
执行流程:根据add_time 索引 全部回表 查找到数据 进行筛选最后直接取出 100条数据 (使用索引排序)
时间消耗:回表200w数据+扫描200w 数据

4使用联合索引 age,weight
执行流程:从索引上直接找到age>20的数据后,扫描索引里面所有weight 筛选出大于70的数据, 回表取数据排序后取出100条数据
时间消耗 回表80w数据+排序80w筛选数据

5:创建 add_time,age,weight 联合索引 ,并且sql 修改成 select * from user where add_time>0 and age>20 and weight<70 order by add_time limit 500000 100;(假如add_time>0)
执行流程:这样会直接扫描整个联合索引,根据age,weight 筛选数据 最后直接取出100条数据 进行回表
时间消耗:扫描200w索引数据+回表100数据

时间消耗:
1: 读取整个表+扫描200w数据+排序100w数据
2:回表100w数据+排序100w数据
3:回表200w数据+扫描200w数据
4:回表80w数据+排序80w筛选数据
5:扫描200w数据+回表100数据

上面看起来好像 4跟5 是时间最少的 尤其是5,看看实际执行情况

实操数据下面实际操作不同环境可能有所差别
1:数据库

在这里插入图片描述
2:数据量 200w
根据上面情况分别测试
1:无所引,耗时 8.3s
在这里插入图片描述在这里插入图片描述
2单列索引:age,消耗时间8.3 跟无所引一样,查看explain 并没有使用索引,强制使用索引 耗时16s左右(这就懵逼了)

在这里插入图片描述
3单列索引:add_time,消耗时间8.3 跟无所引一样,查看explain 不能使用索引!!
在这里插入图片描述
4:使用联合索引 age,weight,消耗时间8.3 跟无所引一样,查看explain 有可用索引并没有使用,跟第2一样

5:使用add_time,age,weight,联合索引 并修改查询语句,消耗时间10.8s,有使用索引,Using index condition 使用索引下推
在这里插入图片描述
测试分析
A:情况3不能使用索引,连possible key 都没有
说明相同数据mysql 回表的速度肯定比排序来的慢,起码大部分情况是这样的
B:情况2,4 有可用索引,但是实际没有使用索引,测试强制使用索引也确实比全表扫描慢
再次证明大量数据回表速度是很慢的,还不如直接读取全表筛选

通过Profiling查看情况1跟情况5的具体时间消耗
情况1无索引情况
在这里插入图片描述
情况5用联合索引(add_time,age,weight)
在这里插入图片描述

这里就有差异了
没用索引主要时间花在 Creating sort index 就是排序;
有索引的情况主要Sending data 简单的说就是mysql 服务层跟 innodb 存储引擎的数据交互,主要是回表时间;
这里不太明白使用了索引下推后为何还需要大量回表,我的理解应该只需要回表100条数据,但时间用了8s多这显然不对

既然情况5 回表是最消耗时间的,那就考虑只取一个ID字段,做到索引覆盖,则不需要回表
测试SQL SELECT id FROM sent_test_u WHERE age>20 and weight<70 ORDER BY add_time LIMIT 500000,100
在这里插入图片描述
执行时间结果为0.4s也是符合预期

最终优化 建立索引(add_tiem,age,weight),首先查找id 然后根据id 查找最后数据,
SELECT * FROM sent_test_u WHERE id in (SELECT id FROM (SELECT id FROM sent_test_u WHERE add_time>0 and age>20 and weight<70 ORDER BY add_time LIMIT 500000,100)as t)=

这样总耗时0.6s

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
魅族16th 是一台功能强大、性能强劲的智能手机,但是自带的系统可能无法满足一些用户的需求,因此很多人选择刷写第三方twrp。下面是魅族16th 刷写第三方twrp 的步骤教程: 1.准备工作 首先需要下载魅族16th 专用的twrp文件,可以在论坛或各大网站上进行下载,同时要确保手机电量充足,防止在刷写时出现意外断电等问题。 2.进入开发者模式 在手机设置中找到开发者选项并打开,这样才能进行之后的操作。同时需要在开发者选项中开启USB调试、OEM解锁和允许未知来源应用程序等选项。 3.连接电脑 将魅族16th 连接到电脑上,确保手机与电脑能够正常相互通信。 4.解锁 bootloader 在电脑上下载fastboot工具,然后在命令行输入 fastboot oem unlock 命令,就可以解锁bootloader。 5.刷写twrp 将下载好的twrp文件放到手机储存中,然后在电脑上打开命令行,输入 adb reboot bootloader 命令,进入bootloader模式,然后输入 fastboot flash recovery twrp.img 命令,就可以刷写twrp了。 6.重启手机 刷写完成后,输入 fastboot reboot 命令,然后等待手机重启即可。此时,你已经成功刷写第三方twrp了。 总的来说,刷写第三方twrp 的过程并不复杂,但是需要十分小心谨慎,避免因为一个小细节导致失败或者损坏手机。如果你有任何疑问或者不明白的地方,建议先参阅论坛帖子或者咨询一些专业人士的意见。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值