MySQL索引失效的10种场景

1 MySQL索引

        索引就类似一本字典的目录,可以方便查找某一个字在一本字典的什么位置。MySQL的索引就是加速数据查询的效率。

        在使用索引时,为了提高查询效率,要尽可能少的从磁盘中读取数据,同时要保证读取数据足够有效。不可能一口气将全量数据都加载进内存,所以要分块读取。在考虑分块读取时,磁盘在和内存交互时是以页(16KB)为单位的,进行读取数据都是页的整数倍。

        聚簇索引和非聚簇索引

                索引列:默认是主键,没有主键选择唯一键,如果也没有唯一键,MySQL会自动生成一个rowid
                索引列和数据绑定在一起的索引称之为聚簇索引
                索引列没有和数据绑定在一起的索引称之为聚簇索引

                InnoDB存储引擎中既有聚簇索引也有非聚簇索引,而MyISAM存储引擎只有非聚簇索引

2 MySQL索引实现原理

        数据结构:B+树

        B+树是MySQL索引结构中最主要的一种结构,除了B+树还有hash索引,它们针对的存储引擎是不同的,大部分情况下是使用B+树。

        为什么要用B+树数据结构?(而不是使用二叉树、红黑树、B树)

        不管是使用二叉树,还是AVL树、红黑树,它们都会有一个问题,树的分支有且仅有2个。当想在树上插入更多的数据时,会造成树的深度很深,树的深度变深会导致查询次数变多,查询效率自然就变慢了。所以要考虑将二叉树变成多叉树,同时要依托有序的特点,就想到了多叉有序树即B树。在数据检索时,B树的数据和key值是放在一起的,就意味着每次数据读取时,一页16KB上有索引+实际数据,这样就会占用大量的存储空间,这样插入更多数据深度会增加。

        非叶子节点只存储key值,叶子节点存储实际数据,这就有了B+树。MySQL还对B+树进行了改造,将叶子节点通过双向指针关联,这样范围查询效率就会大大提升。

3 MySQL索引失效场景        

alter table `user` add index idx_name_age(`name`,`age`);

        3.1 组合索引不遵循最左匹配原则

                按照索引规则查询

explain SELECT * from user where name = 'lisi' and age = 22 and `desc` = '22';

                不遵守最左匹配原则,索引失效

explain SELECT * from user where  age = 22 and `desc` = '22';

        3.2 组合索引的前面索引列使用范围查询(<、>、like),会导致后续的索引失效

                范围查询(>、<、BETWEEN)后的联合索引字段无法继续使用索引‌

                解决:调整索引顺序或拆分查询条件‌

        3.3 不要再索引上做任何操作(计算、函数、类型转换)

EXPLAIN SELECT * from user where name = 1;

        3.4 is null和is not null无法使用索引

                索引默认不存储NULL值,导致无法快速定位‌

        3.5 尽量少使用or操作符,否则连接时索引失效

explain SELECT * from user where name = 'lisi' or age = 22  and  `desc` = '22';

        3.6 字符串不添加引号会导致索引失效

EXPLAIN SELECT * from user where name = 1122;

        3.7 两表关联使用的条件字段中字段的长度、编码不一致会导致索引失效

                字符集和排序规则不一致是索引失效的‌主要原因‌,而字段长度不一致通常影响较小,但可能引发数据截断或隐式转换风险。

        3.8 like语句中,以%开头的模糊查询

                like查询,不以%开头,使用索引

explain SELECT * from user where name like 'li%';

                like查询,以%开头,索引失效

explain SELECT * from user where name like '%li%';

        3.9 如果MySQL中使用全表扫描比使用索引快,也会导致索引失效

                MySQL架构中有一个查询优化器,可能他内部认为全表扫描更快,就不会使用索引

                解决:强制使用索引(如FORCE INDEX)

        3.10 参数化查询的值分布不均

                当查询条件的值分布极端不均时,优化器可能认为全表扫描更快‌

                比如:索引列status的值为0(占比99%)和1(占比1%),查询WHERE status=1可能失效

                解决:强制使用索引(如FORCE INDEX)或优化数据分布‌

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值