mysql 走索引 很慢_MySQL优化:为什么SQL走索引还那么慢?

背景

2019-01-11 9:00-10:00 一个 MySQL 数据库把 CPU 打满了。

硬件配置:256G 内存,48 core

分析过程

接手这个问题时现场已经不在了,信息有限,所以我们先从监控系统中查看一下当时的状态。从 PMM 监控来看,这个 MySQL 实例每天上午九点 CPU 都会升高到 10%-20%,只有 1月 2号 和 1月 11号 CPU 达到 100%,也就是今天的故障。怀疑是业务在九点会有压力下发,排查方向是慢查询。

1. 按执行次数统计 slow log 发现次数最多的一条 sql:

mysqldumpslow -s c slow.log > /tmp/slow_report.txt

Count: 3276 Time=21.75s (71261s) Lock=0.00s (1s) Rows=0.9 (2785), xxx

SELECT T.TASK_ID,

T.xx,

T.xx,

...

FROM T_xx_TASK T

WHERE N=N

AND T.STATUS IN (N,N,N)

AND IFNULL(T.MAX_OPEN_TIMES,N) > IFNULL(T.OPEN_TIMES,N)

AND (T.CLOSE_DATE IS NULL OR T.CLOSE_DATE >= SUBDATE(NOW(),INTERVAL 'S' MINUTE))

AND T.REL_DEVTYPE = N

AND T.REL_DEVID = N

AND T.TASK_DATE >= 'S'

AND T.TASK_DATE <= 'S'

ORDER BY TASK_ID DESC

LIMIT N,N

2. 在 slow log 中找到这条查询记录扫描行数:“Rows_examined: 1161559”,看起来是全表扫描,CPU 升高通常原因就是同时执行大量慢 sql,所以接下来分析这个 sql

3. 因为 T_xxx_TASK 表在现场应急时清理过数据(从110万删至4万行),所以需要用备份恢复该表到故障前。恢复备份后,查看执行计划与执行时间:

explain SELECT T.TASK_ID,

T.xx,

...

FROM T_xxx_TASK T

WHERE 1=1

AND T.STATUS IN (1,2,3)

AND IFNULL(T.MAX_OPEN_TIMES,0) > IFNULL(T.OPEN_TIMES,0)

AND (T.CLOSE_DATE IS NULL OR T.CLOSE_DATE >= SUBDATE(NOW(),INTERVAL '10' MINUTE))

AND T.REL_DEVTYPE = 1

AND T.REL_DEVID = 000000025xxx

AND T.TASK_DATE >= '2019-01-11'

AND T.TASK_DATE <= '2019-01-11'

ORDER BY TASK_ID DESC

LIMIT 0,20;

61b23a84a5236711fbb9c64003b038fe.png

执行时间 10s+:

1 row in set (10.37 sec)

表索引信息:

show index from T_xxx_TASK;

62de9d445390915000ef3419711f8ced.png

看到这里其实已经可以基本确定是这个 SQL 引起的了,因为执行一次就要10s+,而且那个时间点会并发下发大量的这个 SQL。但是有一点陷阱藏在这里:

1. 执行计划中明明有使用到索引,为什么执行还是这么慢?

2. 执行计划中显示扫描行数为 644,为什么 slow log 中显示 100多万行?

a. 我们先看执行计划,选择的索引“INDX_BIOM_ELOCK_TASK3(TASK_ID)”。结合 sql 来看,因为有 "ORDER BY TASK_ID DESC" 子句,排序通常很慢,如果使用了文件排序性能会更差,优化器选择这个索引避免了排序。

那为什么不选 possible_keys:INDX_BIOM_ELOCK_TASK 呢?原因也很简单,TASK_DATE 字段选择度太低了,优化器觉得去这个索引树上找到对应的记录太费劲了(代价太大),所以就不选这个索引了。不过如果我们强制选择这个索引(用 forece index 语法),会看到 SQL 执行速度更快少于10s,那是因为优化器基于代价的原则并不等价于执行速度的快慢;

b. 再看执行计划中的 type:index,"index" 代表 “全索引扫描”,其实和全表扫描差不多,只是扫描的时候是按照索引次序进行而不是行,主要优点就是避免了排序,但是开销仍然非常大。Extra:Using where 也意味着扫描完索引后还需要回表进行筛选。一般来说,得保证 type 至少达到 range 级别,最好能达到 ref。

在第2点中提到的“慢日志记录Rows_examined: 1161559,看起来是全表扫描”,这里更正为“全索引扫描”,扫描行数确实等于表的行数;

c. 关于执行计划中:“rows:644”,其实这个只是估算值,并不准确,我们分析慢 SQL 时判断准确的扫描行数应该以 slow log 中的 Rows_examined 为准。

4. 优化建议:添加组合索引 IDX_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID)

优化过程:

TASK_DATE 字段存在索引,但是选择度很低,优化器不会走这个索引,建议后续可以删除这个索引:

select count(*),count(distinct TASK_DATE) from T_BIOMA_ELOCK_TASK;

+------------+---------------------------+

| count(*) | count(distinct TASK_DATE) |

+------------+---------------------------+

| 1161559 | 223 |

+------------+---------------------------+

在这个 sql 中 REL_DEVID 字段从命名上看选择度较高,通过下面 sql 来检验确实如此:

select count(*),count(distinct REL_DEVID) from T_BIOMA_ELOCK_TASK;

+----------+---------------------------+

| count(*) | count(distinct REL_DEVID) |

+----------+---------------------------+

| 1161559 | 62235 |

+----------+---------------------------+

由于有排序,所以得把 task_id 也加入到新建的索引中,REL_DEVID,task_id 组合选择度 100%:

select count(*),count(distinct REL_DEVID,task_id) from T_BIOMA_ELOCK_TASK;

+----------+-----------------------------------+

| count(*) | count(distinct REL_DEVID,task_id) |

+----------+-----------------------------------+

| 1161559 | 1161559 |

+----------+-----------------------------------+

在测试环境添加 REL_DEVID,TASK_ID 组合索引,测试 sql 性能:

alter table T_BIOMA_ELOCK_TASK add index idx_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID);

添加索引后执行计划:

这里还要注意一点“隐式转换”:REL_DEVID 字段数据类型为 varchar,需要在 sql 中加引号:

AND T.REL_DEVID = 000000025xxx >> AND T.REL_DEVID = '000000025xxx'

18c4074568eddca662594d72bf592115.png

执行时间从 10s+ 降到 毫秒级别:

1 row in set (0.00 sec)

结论

一个典型的 order by 查询的优化,添加更合适的索引可以避免性能问题:

执行计划使用索引并不意味着就能执行快,要看 type 类型,如果对执行计划不是很了解,可以移步另一篇文章:https://www.jianshu.com/p/27494df83a92

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/514059.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为徐直军:以持续创新加快数字化发展

【中国 深圳】2021年9月23日&#xff0c;华为全联接大会以线上形式举行&#xff0c;今年的全联接大会以“深耕数字化”为主题&#xff0c;汇聚了业界思想领袖&#xff0c;商业精英&#xff0c;技术大咖&#xff0c;生态伙伴等&#xff0c;探讨如何深入业务场景&#xff0c;把数…

大型 Web 应用插件化架构探索

简介&#xff1a; 随着 Web 技术的逐渐成熟&#xff0c;越来越多的应用架构趋向于复杂&#xff0c;例如阿里云等巨型控制台项目&#xff0c;每个产品下都有各自的团队来负责维护和迭代。不论是维护还是发布以及管控成本都随着业务体量的增长而逐渐不可控。在这个背景下微前端应…

高精地图技术专栏 | 基于空间连续性的异常3D点云修复技术

简介&#xff1a; 我们需要通过激光的内部机制和数据处理算法&#xff0c;将这些噪声恢复到它本来的位置。本文会从MTA问题产生的原理、激光应对MTA的内部机制、数据处理算法三方面来介绍高精资料处理是如何解决这个问题的。 1.背景 1.1 高精资料采集 高精采集车是集成了测绘…

pytorch 图像分割的交并比_「通知」《深度学习之图像识别》再版工作启动,欢迎指导和提建议...

不知不觉有三第一本书也上市超过1年半了&#xff0c;第一次写作略显稚嫩&#xff0c;许多细节处理不当&#xff0c;比如没有在印刷前核对公式&#xff0c;被删掉了参考文献影响读者阅读体验等。现在本书正式启动再版工作&#xff0c;注意不是重印&#xff0c;是再版。重印只是修…

mysql实例怎么复制_Mysql实例MySQL数据库复制概论

《Mysql实例MySQL数据库复制概论》要点&#xff1a;本文介绍了Mysql实例MySQL数据库复制概论&#xff0c;希望对您有用。如果有疑问&#xff0c;可以联系我们。导读&#xff1a;每当我们讨论一项(新的)领域技术的时候,最好的方式通常是首先抛出一些问题,这些问题大致分为三类&a…

app inventor离线版_百度要哭了!今日头条出了搜索引擎了,还做了APP

今天小编为大家送上几条新闻了&#xff1a;1 微软给Edge浏览器添加离线小游戏谷歌浏览器在不联网的情况下&#xff0c;会有一个小恐龙跳一跳的游戏&#xff0c;而最近换上chromium内核的edge&#xff0c;也添加了自己的离线小游戏。这是一款冲浪游戏&#xff0c;非常类似于微软…

打车业务下单高并发解决方案

简介&#xff1a; 打车业务下单高并发解决方案前言 在技术领域有一条准则&#xff0c;即不存在银弹技术。在实际工作中&#xff0c;通常无法通过几项简单的技术组合就解决实际业务中各种场景下的复杂问题。虽然追求架构的简单简洁也是架构师的目标之一。但必须认识到架构的简单…

Serverless 时代 DevOps 的最佳打开方式

简介&#xff1a; 传统软件开发过程中&#xff0c;开发和运维是极其分裂的两个环节&#xff0c;运维人员不关心代码是怎样运作的&#xff0c;开发人员也不知道代码是如何运行的。 作者 | 许成铭&#xff08;竞霄&#xff09; 来源 | 阿里巴巴云原生公众号 DevOps 简析 传统软…

2020 q5l使用手册电子版_关于2020下半年自考本科毕业生论文预答辩题目查询的通知...

一、对象&#xff1a;2020下半年获论文预答辩资格毕业生(名单见附件1)二、查询方法&#xff1a;请登录以下网址&#xff1a; 输入个人准考证和姓名&#xff0c;查询论文预答辩题目。三、相关要求1. 请将《自学考试本科毕业论文预答辩记录表》(见附件2)中个人相关信息以及预答辩…

现实版“奇异博士”?原来是这款神秘的“数学黑盒”

简介&#xff1a; 现实版“奇异博士”&#xff1f;原来是这款神秘的“数学黑盒”供稿团队&#xff1a;阿里云市场部在漫威电影《复联3》中&#xff0c;奇异博士预测到未来有1400多万种可能&#xff0c;而胜利却只有一种&#xff0c;这唯一的最优解成为他们战斗的希望。只可惜&a…

如何在Spring生态中玩转RocketMQ?

简介&#xff1a; RocketMQ作为业务消息的首选&#xff0c;在消息和流处理领域被广泛应用。而微服务生态Spring框架也是业务开发中最受欢迎的框架&#xff0c;两者的完美契合使得RocketMQ成为Spring Messaging实现中最受欢迎的消息实现。本文展示了5种在Spring生态中文玩转Rock…

enum 有什么好处_林卡尔|先买地板后装修的三大好处

【中华地板网】现在很多装饰公司和设计师&#xff0c; 提倡的装修新模式——“先定地板后装修”。 后装修并不是买完地板后再开工&#xff0c; 而是在开工之前&#xff0c; 先把地板风格、颜色、尺寸、价位定下&#xff0c; 然后让设计师根据地板进行其他设计。 那么这样做究竟…

华为推出业界首个分布式云原生产品:华为云UCS,持续创新,深耕数字化

华为面向ICT产业的全球年度旗舰活动——华为全联接2021拉开序幕。华为轮值董事长徐直军进行了“以持续创新加快数字化发展”的大会主题演讲。 本次大会围绕“深耕数字化”主题&#xff0c;探讨如何深入业务场景&#xff0c;把数字技术与行业知识深度结合&#xff0c;解决核心业…

Flink 必知必会经典课程四:Fault-tolerance in Flink

简介&#xff1a; 本文由 Apache Flink PMC , 阿里巴巴高级技术专家李钰分享&#xff0c;主要从有状态的流计算、全局一致性快照 、Flink的容错机制、Flink的状态管理 四个方面介绍 Flink 的容错机制原理。 作者 | 李钰 分享人&#xff1a;本文由 Apache Flink PMC , 阿里巴巴…

用云原生的思维践行云原生,华为云深耕数字化,一切皆服务

[中国&#xff0c;深圳&#xff0c;2021年9月23日] 华为全联接2021于9月23日开幕。华为轮值董事长徐直军进行了“以持续创新加快数字化发展”的主题演讲&#xff0c;发布业界首个分布式云原生产品——华为云UCS&#xff0c;即 “无处不在的云原生服务”。华为高级副总裁、华为云…

白苹果了怎么办_苹果手机出现白苹果、死机、不断重启怎么办?

小伙伴们的苹果设备是否出现过白苹果、不断重启、更新失败、卡机死机、进入了恢复模式等情况呢?小编自己的iPhoneXR就遇到过&#xff0c;不知道怎么操作的就进入了恢复模式&#xff0c;有时候手机卡机需要强制重启&#xff0c;遇到问题就想去外面的修理店解决一下&#xff0c;…

Knative 多容器支持介绍

简介&#xff1a; 微服务和容器化带来了将应用程序分解成可重复使用的小型单元的诉求&#xff0c;这些单元通常作为单独的进程运行&#xff0c;或者在单独的容器运行。 Kubernetes的Pod模型允许用户创建一个部署单元&#xff0c;该单元可以打包多个容器作为应用程序的单个实例。…

GitHub Action + ACK:云原生 DevOps 落地利

简介&#xff1a; 据信通院《中国 DevOps 现状调查报告&#xff08;2020年&#xff09;》显示&#xff0c;63% 的企业已经实践落地 DevOps&#xff0c;采用持续交付流水线打通开发、测试、部署和运维多个环节。但是依然有 20% 的企业反馈实践 DevOps 复杂&#xff0c;自建 Jenk…

win7硬盘安装工具_如何重装电脑安装Win7 系统?最简单,最便捷的办法,值得收藏...

没有U盘、没有光盘怎么安装Win7系统&#xff1f;最简单、最方便的就是用硬盘安装了。在保证能进入系统的前提下&#xff0c;本地硬盘安装Win7系统&#xff0c;能够让你快速体验新的Win7系统。一、安装前准备保证能够正常进入系统&#xff1b;下载Win7系统&#xff1a;64位&…

网络架构优化--云企业网典型场景分析for客户

简介&#xff1a; 网络架构优化--云企业网典型场景分析for客户1. 背景描述 客户从传统的高速通道迁移到云企业网&#xff0c;加入云企业网的VPC&#xff0c;VBR默认全通&#xff0c;但是实际业务场景需要更严格的策略做选择性放通。此外&#xff0c;由于测试账号没有实际专线和…