MySQL之SQL分析三部曲实际案例(二)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 附上MySQL之SQL分析三部曲地址http://blog.itpub.net/29510932/viewspace-1709732/ --------------------------------------------------------------...
附上MySQL之SQL分析三部曲地址http://blog.itpub.net/29510932/viewspace-1709732/

-------------------------------------------------------------------------------------------------正文--------------------------------------------------------------------------------------------------------------

由于是生产环境下进行的,截图和SQL都隐去了一些信息

背景:有用户在抱怨生产系统上,某一个Web的页面太慢,忍无可忍
问题分析过程:略
问题聚焦:最终确定是另一个SQL语句太慢,查询时间用了14s(慢查询日志给出的信息)
罪魁祸首的SQL语句:

点击(此处)折叠或打开

  1. select count(*)
  2. from tom
  3. inner toa on tom.oid = toa.oid
  4. inner toi on tom.oid = toi.oid
  5. left join fo on tom.stype = 2 and fo.oid = tom.oid
  6. WHERE ( tom.ptime >= '2333-01-07 08:44:50.624' and tom.ptime = '2333-01-14 08:44:50.624' and tom.sid in ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 ) )
SQL分析三部曲之一:explain,结果如下图

这次的问题比第一个案例变麻烦了,因为explain中,优化器计算出来的rows并不高,然而事实是话费的执行时间是不可接受的
回头看看tom表的索引,发现优化器选择的是sid的索引,但是本身还存在另外一个的联合索引,那是不是和案例一一样,是索引选择错误?
那么explain看看

意料之外的结果........rows多得多,但是从常规来说,联合索引应该是会好一些的,所以实际跑跑效果试试

结果只能说是意料之中.....


那么问题来了, 和案例一不同,优化器确实是选择了rows->cost比较少的执行计划,但是实际上,这个语句执行的时间和优化器计算的cost完全反过来了!

为什么?

SQL分析三部曲之二: profile,拖慢SQL的主要问题在于优化器计算出来的cost有问题,因此不必用profile来寻找时间消耗的主要目标

SQL分析三部曲之三:optimizer_trace,操作过程略 ,部分结果如图

方框所示的索引就是sid的索引,箭头所指的索引就是的联合索引,可以看到优化器认为两个索引都能用

看看这两个索引的cost计算

左边的是错误的索引的cost,右边是联合索引的cost,优化器确确实实是计算出来了cost,虽然这个cost和实际情况并不相符
箭头所指的地方就是这个答案啦~~~
原因也比较简单,因为优化器在计算cost的时候,也是参照一个固定的cost模型来计算的,而且有很多entries的具体值(行数,索引叶子数,IO等)都是估计值(案例一发生问题的地方
同时,在计算cost的时候,优化器的计算方式,也是会根据MySQL本身的一些参数来改变的
比如说这个参数:index_dives_for_eq_ranges,主要会影响到等值计算,包括,但可能不限于逻辑运算=,in,或者其他(查看trace可以知道最终MySQL改写的语句)
当SQL语句中的等值计算的数量超过这个值的时候,trace中的这个值会变成false,这意味着MySQL的优化器认为计算这种执行计划的cost可能会花费较多的时间,从而采用一种更加高效,但是不精确的估计值计算方式
而在联合索引的计算当中,这个值变为了true,这意味这优化器在计算这种执行计划的时候,采用的是更加精确的cost计算方式,虽然计算的过程会多花点时间。(为什么联合索引就变成true?个人推测是联合索引排除了很多的无用数据,所以虽然in中的值比较多,但是本身数据基数少了,做精确计算并不会多花太多时间,因此使用了精确计算)
单独使用的索引时,由于in里面的值超过了设定的数量,所以采用了相对不精确的计算方式,得出了错误的cost
原因已经分析出来,现在去验证一下是不是这个原因,先看一下默认的值

in中的值超过了10个,预料之中,那么修改一下,看看新的explain和trace


可以看到执行计划已经变成了使用联合索引,rows的估计值也变成了30000多,那么抱着一丝好奇心,使用索引的真正的cost是多少?
看一下trace的内容

index_dives_for_eq_ranges的值已经变成了true,在精确的计算方式下,真正的rows和cost已经揭晓~~惨不忍睹........
choosen:true?不是true就不会计算cost了~
可以看到
之前的判断是正确的,由于index_dives_for_eq_ranges相关的值的原因,导致MySQL在计算cost的时候,对不同索引采用了不同的策略。
完结撒花~~MySQL的优化器真是坑~~真是真的坑~over


PS:具体index_dives_for_eq_ranges相关的值是如何影响优化器的判断的,只能通过源码去分析了,在以后应该会好好整理一下,有生之年系列+1,记在小本子上面~

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1天前
|
SQL Oracle 关系型数据库
SQL(MySQL)
SQL语言是指结构化查询语言,是一门ANSI的标准计算机语言,用来访问和操作数据库。 数据库包括SQL server,MySQL和Oracle。(语法大致相同) 创建数据库指令:CRATE DATABASE websecurity; 查看数据库:show datebase; 切换数据库:USE websecurity; 删除数据库:DROP DATABASE websecurity;
|
2月前
|
关系型数据库 MySQL 数据库
一个 MySQL 数据库死锁的案例和解决方案
本文介绍了一个 MySQL 数据库死锁的案例和解决方案。
79 3
|
2月前
|
存储 关系型数据库 MySQL
基于案例分析 MySQL 权限认证中的具体优先原则
【10月更文挑战第26天】本文通过具体案例分析了MySQL权限认证中的优先原则,包括全局权限、数据库级别权限和表级别权限的设置与优先级。全局权限优先于数据库级别权限,后者又优先于表级别权限。在权限冲突时,更严格的权限将被优先执行,确保数据库的安全性与资源合理分配。
|
2月前
|
SQL 运维 关系型数据库
MySQL 运维 SQL 备忘
MySQL 运维 SQL 备忘录
47 1
|
1月前
|
SQL 关系型数据库 MySQL
MySql5.6版本开启慢SQL功能-本次采用永久生效方式
MySql5.6版本开启慢SQL功能-本次采用永久生效方式
38 0
|
1月前
|
SQL 关系型数据库 MySQL
mysql编写sql脚本:要求表没有主键,但是想查询没有相同值的时候才进行插入
mysql编写sql脚本:要求表没有主键,但是想查询没有相同值的时候才进行插入
31 0
|
3月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
5月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
118 13
|
5月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
5月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
63 6