MySQL为什么会选错索引

有的时候,我们加了索引,也不一定最终查询语句就能用上索引,因为Innodb要不要使用索引,该使用哪个索引是优化器决定的,它是根据成本(代价)预估来选择的,他会倾向于选择一个成本最低的方式进行查询。

原因

基数性(Cardinality)

索引的基数性其实就是我们通常说的区分度,表示索引中不同值的数量。基数性越高,索引区分度越好,优化器越倾向于使用该索引。

选择性(Selectivity)

选择性是指索引过滤数据的能力。高选择性意味着索引能过滤掉更多的行,优化器会偏向于使用这样的索引。

这个因素是决定着扫描行数的关键。同一个查询语句,选择性更高的索引会使得扫描行数更少。

索引覆盖

如果一个查询可以完全通过索引来解决,即所需的所有列都包含在索引中,优化器会倾向于使用这样的"覆盖索引"。

ORDER BY

为了避免额外的排序操作,当SQL语句中有ORDER BY时,如果这个字段有索引,那么优化器为了减少file sort,会愿意选择使用这个索引,因为索引天然有序。

索引类型

不同类型的索引(如B-TREE、HASH、FULLTEXT等)适用于不同类型的查询。优化器会根据查询类型选择最合适的索引。

JOIN类型和顺序

对于包含JOIN的查询,优化器会考虑使用哪些索引以及JOIN的顺序。

索引的大小和深度

较小、较浅的索引通常更快,因为它们占用更少的磁盘空间,可以更快地加载到内存中。

访问类型

访问类型,如范围查询、点查找、扫描等,也会影响索引的选择。例如,某些索引可能更适合范围查询。

内存使用

对于大型表,优化器还会考虑执行计划的内存使用情况,尽量避免造成过多的内存占用。

系统资源限制

优化器还会考虑系统的资源限制,如内存和磁盘I/O。

查询缓存

如果启用了查询缓存且相同的查询已被缓存,优化器会使用这个缓存的结果而不是选择新的索引。

这里面比较重要的因素就是索引的基数性(区分度)、索引的选择性(扫描行数)、是否有索引覆盖等这几个。

因为如何选择索引是由以上这些因素共同决定的,所以最终选错了索引,可能有以下几个原因:

不准确的统计信息

InnoDB存储引擎依赖统计信息来决定使用哪个索引,如基数性、选择性这些都是统计信息。如果这些统计信息过时或不准确,优化器可能做出错误的决策。

复杂的查询逻辑

对于复杂的查询,尤其是那些包含多表join、子查询、函数等的查询,优化器可能难以准确判断哪个索引最有效。

系统和配置因素

MySQL的配置设置和系统资源限制(如内存大小)也会影响优化器的决策。

==================================================================

如何解决

如果发现mysql选择了一个错误的索引,一般来说有以下几种解决方式:

更新统计信息

定期运行ANALYZE TABLE命令来更新表的统计信息。这可以帮助优化器更准确地评估各个索引的有效性。

使用强制索引(FORCE INDEX)

如果我们确定某个索引比优化器选择的更有效,可以在查询中使用FORCE INDEX来强制使用特定索引。

如SELECT * FROM hollis_test_table FORCE INDEX (idx_name) WHERE name ='wutongshu';

但是,FORCE INDEX 应该谨慎使用,因为强制使用特定的索引可能会导致性能下降,特别是当表的数据分布发生变化时。在使用之前,应该确保理解该索引为什么是最好的选择,并且定期评估其效果。

优化查询

简化查询逻辑,尽量避免复杂的连接和子查询,这有助于优化器做出更好的决策。

调整索引

我们可以为where条件中的过滤条件创建更合适的索引,并尽可能考虑创建复合索引来提高查询效率,尤其是对于多列的过滤和排序。

调整MySQL配置

根据系统的资源和需求调整MySQL的配置参数,比如缓冲池大小(innodb_buffer_pool_size)。

相关推荐
无为之士3 分钟前
Linux自动备份Mysql数据库
linux·数据库·mysql
小汤猿人类16 分钟前
open Feign 连接池(性能提升)
数据库
阳冬园37 分钟前
mysql数据库 主从同步
数据库·主从同步
XiaoH2331 小时前
培训机构Day15
sql·mysql
ThisIsClark1 小时前
【后端面试总结】MySQL主从复制逻辑的技术介绍
mysql·面试·职场和发展
Mr.132 小时前
数据库的三范式是什么?
数据库
Cachel wood2 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Python之栈2 小时前
【无标题】
数据库·python·mysql
风_流沙2 小时前
java 对ElasticSearch数据库操作封装工具类(对你是否适用嘞)
java·数据库·elasticsearch
亽仒凣凣2 小时前
Windows安装Redis图文教程
数据库·windows·redis