五分钟,让你明白MySQL是怎么选择索引《死磕MySQL系列 六》

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: 五分钟,让你明白MySQL是怎么选择索引《死磕MySQL系列 六》

如果你对索引的知识点还不太清楚,可以直接通过传送门查看咔咔总结的索引知识点。


揭开MySQL索引神秘面纱


索引是为加速查询速度,创建的索引也符合所有规则,但MySQL就是不使用理想的索引,导致查询速度变慢并产生大量慢查询记录。


今天就从这个问题来聊聊MySQL选择索引时都做一些什么事情。


一、如何选择索引

影响优化器的几大因素

一条查询SQL执行需要经过连接器、分析器、优化器、执行器,而选择索引的重任就交给了优化器。


优化器在多个索引中选择目的是为了找出执行代价最低的方案。


影响优化器选择无非就这几个因素,扫描行数、是否使用了临时表、是否使用文件排序。


临时表、文件排序这个两个点会在后期文章给大家慢慢引出,今天只聊扫描行数。


扫描行数越少则访问磁盘数据的次数就越少,消耗的CPU资源越少。


那么这个扫描行数是从哪里取的呢?


扫描行数从何而来?

创建索引一直提倡大家给区分度高的列建立索引,在一个索引上不同值的个数称之为基数(cardinality)。


使用show index from table_name可以查看每个索引的基数是多少。


image.png


索引基数怎么计算


MySQL使用采样统计的方法,会选出N个数据页,每个数据页大小16kb,接着统计选出来的数据页上的不同值就会得到一个平均值,用平均值在乘以索引的页面数得到的结果就是这个索引的基数。


表数据是持续增加或删减的,统计的这个数据也不是时时变化的,当变更的数据超过1/M时会自动触发重新计算。


这个M是根据参数innodb_stats_persistent的值选则的,设置为on值为10,设置为off值为16。


索引基数通过这种方式计算不是精准的但也差不了多少


为什么优化器选择了扫描行数多的索引?

第一种情况


表增删十分频繁,导致扫描行数不准确


第二种情况


假设你主键索引扫描行数是10W行,而普通索引需要扫描5W行,这种情况就会遇到优化器选择了扫描行数多的。


在索引那一期文章中知道主键索引是不需要回表的,找到值直接就返回对应的数据了。


而普通索引是需要先拿到主键值,再根据主键值获取对应的数据,这个过程优化器选择索引时需要计算的一个成本。


如何解决这种情况


扫描行数不准确时可以执行analyze table table_name命令,重新统计索引信息,达到预期优化器选择的索引。


二、索引选择异常如何处理

方案一


在MySQL中提供了force index来强制优化器使用这个索引。


使用方法:select * from table_name force index (idx_a) where a = 100;


但别误解force index的使用方法,之前在代码中看到这样一个案例,给查询列使用了函数操作导致使用不上索引,然后这哥们就直接使用force index,肯定不行的哈!


当优化器没有正确选择索引时是可以使用这种方案来解决。


缺点


使用force index的缺点相信大家也知道就是太死板,一旦索引名字改动就会失效。


方案二


删掉误选的索引,简单粗暴,很多索引建立其实也是给优化器的一个误导,直接删掉即可。


方案三


修改SQL语句,主动引导MySQL使用期望的索引,一般情况这种做法使用的很少除非你对系统十分熟悉,否则尽量少操作。


三、总结

优化器选择索引首先会根据扫描行数再由执行成本决定。


当索引统计信息不准确时,使用analyze table 解决。


优化器选择了错误的索引,只用force index来快速矫正,再通过优化SQL语句来引导优化器选择正确的索引,最暴力的手法是直接删除误选的索引。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4天前
|
JSON 关系型数据库 MySQL
✅MySQL用了函数到底会不会导致索引失效
MySQL 8.0 引入了函数索引,打破了传统观念,允许在索引中使用函数,提升查询性能。通过创建基于表达式的索引,如 `CONCAT`、`SUBSTRING_INDEX`、`YEAR`、`MONTH` 等,可以优化涉及这些函数的查询。虽然提高了某些查询速度,但也会增加数据维护成本。应谨慎使用,确保表达式确定且适用于常见查询模式。示例包括基于字符串、日期、数学运算和JSON属性的索引。
✅MySQL用了函数到底会不会导致索引失效
|
9天前
|
关系型数据库 MySQL 数据库
MySQL索引优化:深入理解索引合并
MySQL索引优化:深入理解索引合并
|
10天前
|
存储 关系型数据库 MySQL
MySQL索引详解
MySQL索引详解
|
10天前
|
关系型数据库 MySQL 分布式数据库
PolarDB产品使用问题之mysql迁移后查询不走索引了,该如何解决
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
11天前
|
关系型数据库 MySQL 测试技术
深入探索MySQL 8:隐藏索引与降序索引的新特性
深入探索MySQL 8:隐藏索引与降序索引的新特性
|
10天前
|
存储 关系型数据库 MySQL
架构面试题汇总:mysql索引汇总(2024版)
架构面试题汇总:mysql索引汇总(2024版)
|
11天前
|
存储 SQL 关系型数据库
|
12天前
|
存储 关系型数据库 MySQL
Mysql优化之索引相关介绍(笔记)
索引查找从顶层节点开始查找,通过key值,也就是主键的值进行比较,最终定位到存储数据的叶子节点上面,从叶子节点取出响应的数据。
35 0
Mysql优化之索引相关介绍(笔记)
|
2天前
|
关系型数据库 MySQL 数据库
MySQL索引的类型与优化方法
MySQL索引的类型与优化方法
|
4天前
|
存储 关系型数据库 MySQL
MySQL索引设计原则与优化策略
MySQL索引设计原则与优化策略