MySQL之SQL分析三部曲实际案例(六)--file sort与key_len

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: -------------------------------------------------------------------------------------------------正文-----------------------------------...
-------------------------------------------------------------------------------------------------正文---------------------------------------------------------------------------------------------------------------
问题发生于对即将上线的SQL进行review时,实际问题的截图隐去部分生产环境信息,试验环境构造于测试数据库
所有操作都是基于MySQL-5.6.26下进行的,补充实验在MySQL-5.7.9-GA环境下进行了简单验证

背景:开发人员在测试环境测试SQL时发现文件排序没有走索引
问题分析过程:下文详细描述
问题聚焦:优化器为什么没有走索引去排序,以及key_len的延伸

出问题的SQL语句(同类型的问题构造)

点击(此处)折叠或打开

  1. select * from t_order_main 
  2. where outer_order_id >= '1' and outer_order_id <= '3'
  3. and pay_time>='2014-11-11 00:00:00' and pay_time<='2014-11-11 23:59:59'
  4. order by order_id;

问题描述:开发在测试环境的表上面建立了 outer_order_id,  pay_time,  order_id的联合索引, 希望解决explain里面出现的file sort的问题,
但是加了索引以后,发现explain的输出结果中还是存在filesort,结果如下图
索引

执行计划

可以看到虽然有索引可以同时覆盖到选择条件和排序列, 但是MySQL的优化器没有选择那个联合索引,而是选择了两个where条件的联合索引
既然要看优化器的一些信息,那么就去trace里面找找吧~一组使用正常的优化器逻辑,一组使用force来指定索引,截取部分信息截图
正常的优化器选择逻辑,可以看到优化器估计的cost是2.2

强制指定索引,

索引的代价是一样的

但是在排序的时候, 这个联合索引的最后一列没有用上


从这两个对比里面很容易看出来, 优化器认为走索引去排序并不好,而且三列的联合索引和两列的联合索引都是一样的cost,自然也就不会去使用相对体积更大的三列联合索引了。
结论:MySQL对比两种索引策略的cost以后,认为使用索引去排序没有必要,所以选择了体积相对比较小的两列联合索引,
这种情况多发生于最终结果集比较小的时候,排序的操作就可以完全放在内存,而不用读索引,然后再回表取数据,所以虽然联合索引有排序列,但是MySQL并不会去使用。

延伸:有一个很有意思的现象,这两个索引的结构不一样,但是key len却是一样的,原因
对比一下强制索引和默认索引的explain,有一个比较有意思的现象:两个执行计划的key len都是103~但是这两个索引的结构是不一样的;


引用前辈的总结(出处同下面的 key len计算方式): key len表明了在这次查询中,所用到的索引的长度,所用到的,意味着,如果索引的某些列没有用到,那就不会计算在这个长度里面;
这段介绍也证实了在之前,虽然索引结构不一样,但是都只用到了一部分的索引列,那么这意味着可以通过key_len来判断实际执行中用到了多少列。
问题就变成了,这个key len是怎么算出来的?
索引对应的几个列的结构



数据结构对应的key len计算方式,一部分引用现有的资料(出处http://imysql.com/2015/10/20/mysql-faq-key-len-in-explain.shtml)

补充一个 用到的datetime的属性,计算key_len的时候为5(如果带上了小数精度,这个长度会变化,从5-8不等)
那么开始计算一下len:
outer_order_id = 32x3(UTF-8)+2(变长)=98
pay_time = 5
可以看到截图中的key_len刚好是98+5=103,说明这个执行计划使用了 outer_order_id 和 pay_time~
可是,执行计划里面真的用了pay_time?
在trace里面
我们可以看到在计算索引的代价的时候,列出了使用索引的选择条件和索引

是的,在分析索引代价的时候,没有pay_time,这说明索引中的pay_time并没有被用来优化where条件里面的逻辑,
但是key_len里面确确实实把pay_time的这一部分加上了,那么他用到哪里去了?
看看最前面截图的表结构,然后为explain增加一点额外的输出, 看看分区表的分区信息

很明显可以看到, 这个查询指向了一个单独的分区p0,真相大白~本次查询用到了pay_time,但是不是用来优化where条件的筛选,而是用在了分区条件的判断上!
作为对比,去掉pay_time的条件看看,

长度也变成了98, 分区也从p0变成了所有~

-------------------------------------------------------------------------------------------------结论---------------------------------------------------------------------------------------------------------------
MySQL会有一套Cost计算模型来判断多种索引的代价,file sort的出现,并非代表着这个语句的效率不好,因为结果集并不大的时候,纯内存的排序并不会有太高的开销,
通过走索引避免排序,然后再用随机读的方式回表反而会消耗更多的时间(随机读的开销很高
explain的key_len会反应 本次查询使用的索引的列的情况,不仅是使用在where条件里面的列,也包括判断分区条件使用到的索引列。

-------------------------------------------------------------------------------------------------附录---------------------------------------------------------------------------------------------------------------
附上其他类型的key_len的实验,请对照截图信息食用~ 测试环境MySQL-5.7.9-GA,本质上没什么区别
PS:请无视中间那个失误...
表结构

部分测试结果

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
5月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
446 158
|
4月前
|
存储 消息中间件 监控
MySQL 到 ClickHouse 明细分析链路改造:数据校验、补偿与延迟治理
蒋星熠Jaxonic,数据领域技术深耕者。擅长MySQL到ClickHouse链路改造,精通实时同步、数据校验与延迟治理,致力于构建高性能、高一致性的数据架构体系。
MySQL 到 ClickHouse 明细分析链路改造:数据校验、补偿与延迟治理
|
5月前
|
SQL 数据可视化 关系型数据库
MCP与PolarDB集成技术分析:降低SQL门槛与简化数据可视化流程的机制解析
阿里云PolarDB与MCP协议融合,打造“自然语言即分析”的新范式。通过云原生数据库与标准化AI接口协同,实现零代码、分钟级从数据到可视化洞察,打破技术壁垒,提升分析效率99%,推动企业数据能力普惠化。
473 3
|
5月前
|
缓存 监控 关系型数据库
使用MYSQL Report分析数据库性能(中)
使用MYSQL Report分析数据库性能
435 156
|
5月前
|
缓存 监控 关系型数据库
使用MYSQL Report分析数据库性能(上)
最终建议:当前系统是完美的读密集型负载模型,优化重点应放在减少行读取量和提高数据定位效率。通过索引优化、分区策略和内存缓存,预期可降低30%的CPU负载,同时保持100%的缓冲池命中率。建议每百万次查询后刷新统计信息以持续优化
531 161
|
4月前
|
NoSQL 算法 Redis
【Docker】(3)学习Docker中 镜像与容器数据卷、映射关系!手把手带你安装 MySql主从同步 和 Redis三主三从集群!并且进行主从切换与扩容操作,还有分析 哈希分区 等知识点!
Union文件系统(UnionFS)是一种**分层、轻量级并且高性能的文件系统**,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem) Union 文件系统是 Docker 镜像的基础。 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
642 5
|
5月前
|
SQL 关系型数据库 MySQL
Mysql数据恢复—Mysql数据库delete删除后数据恢复案例
本地服务器,操作系统为windows server。服务器上部署mysql单实例,innodb引擎,独立表空间。未进行数据库备份,未开启binlog。 人为误操作使用Delete命令删除数据时未添加where子句,导致全表数据被删除。删除后未对该表进行任何操作。需要恢复误删除的数据。 在本案例中的mysql数据库未进行备份,也未开启binlog日志,无法直接还原数据库。
|
6月前
|
存储 关系型数据库 MySQL
深入理解MySQL索引类型及其应用场景分析。
通过以上介绍可以看出各类MySQL指标各自拥有明显利弊与最佳实践情墁,在实际业务处理过程中选择正确型号极其重要以确保系统运作流畅而稳健。
224 12
|
7月前
|
存储 SQL 关系型数据库
MySQL的Redo Log与Binlog机制对照分析
通过合理的配置和细致的管理,这两种日志机制相互配合,能够有效地提升MySQL数据库的可靠性和稳定性。
254 10
|
7月前
|
SQL 关系型数据库 MySQL
MySQL group by 底层原理详解。group by 执行 慢 原因深度分析。(图解+秒懂+史上最全)
MySQL group by 底层原理详解。group by 执行 慢 原因深度分析。(图解+秒懂+史上最全)
MySQL group by 底层原理详解。group by 执行 慢 原因深度分析。(图解+秒懂+史上最全)

推荐镜像

更多