什么情况下会造成索引失效?

2024-05-14 22:20

本文主要是介绍什么情况下会造成索引失效?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2.3.4. 索引失效

  1. 对索引使用左或者左右模糊匹配

使用左或者左右模糊匹配的时候,也就是 like %xx 或者 like %xx% 这两种方式都会造成索引失效。但是如果前缀是确定的那么就可以使用到索引,例如 name like '许%'。

因为索引 B+ 树是按照「索引值」有序排列存储的,只能根据前缀进行比较。如果使用 name like '%许' 方式来查询,查询的结果可能是「小许、大许、老许」等之类的,存储引擎不知道从哪个索引值开始比较,于是就只能通过全表扫描的方式来查询。

  1. 对索引使用函数

查询条件中对索引字段使用函数,就会导致索引失效。因为索引保存的是索引字段的原始值,而不是经过函数计算后的值,自然就没办法走索引了。

MySQL 5.7 开始,索引特性增加了函数索引,即可以针对函数计算后的值建立一个索引,也就是说该索引的值是函数计算后的值,所以就可以通过扫描索引来查询数据。

-- 对 length(name) 的计算结果建立一个名为 idx_name_length 的索引。
alter table t_user add key idx_name_length ((length(name)));
  1. 对索引进行表达式计算

在查询条件中对索引进行表达式计算,也是无法走索引的。例如,下面代码

explain select * from t_user where id + 1 = 10;

如果把查询语句的条件改成 where id = 10 - 1,这样就不是在索引字段进行表达式计算了,于是就可以走索引查询了。

因为索引保存的是索引字段的原始值,而不是 id + 1 表达式计算后的值,所以无法走索引,只能通过把索引字段的取值都取出来,然后依次进行表达式的计算来进行条件判断,因此采用的就是全表扫描的方式。

个人觉得这种方式完全可以不使用没必要这么麻烦。

  1. 对索引隐式类型转换

索引字段是字符串类型,查询条件种输入的参数是整型,在执行计划里发现这条语句会走全表扫描。

索引字段是整型类型,查询条件中的输入的参数是字符串,不会导致索引失效,还是可以走索引扫描。

-- 例1、索引是字符串 参数是整型
select * from t_user where phone = 1300000001;
-- 例2、索引是整型 参数是字符串
select * from t_user where id = '1';

因为MySQL 在遇到字符串和数字比较的时候,会自动把字符串转为数字,然后再进行比较

-- 例1
select * from t_user where CAST(phone AS signed int) = 1300000001;-- 例2
select * from t_user where id = CAST("1" AS signed int);

例1,CAST 函数是作用在了 phone 字段,而 phone 字段是索引,也就是对索引使用了函数!

例2,索引字段并没有用任何函数,CAST 函数是用在了输入参数,所以可以走索引扫描的。

  1. 组合索引非最左匹配

如果创建了一个 (a, b, c) 组合索引,因为有查询优化器,所以 a 字段在 where 子句的顺序并不重要。

如果查询条件是以下这几种,因为不符合最左匹配原则,所以就无法匹配上联合索引,联合索引就会失效:

  • where b=2;
  • where c=3;
  • where b=2 and c=3;

比较特殊的查询条件:where a = 1 and c = 3 ,符合最左匹配吗?

MySQL 5.5 的话,前面 a 会走索引,在联合索引找到主键值后,开始回表,到主键索引读取数据行,Server 层从存储引擎层获取到数据行后,然后在 Server 层再比对 c 字段的值。

从 MySQL 5.6 之后,有一个索引下推功能,可以在存储引擎层进行索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,再返还给 Server 层,从而减少回表次数。

在组合索引的情况下,数据是按照索引第一列排序,第一列数据相同时才会按照第二列排序。

如果我们想使用联合索引中尽可能多的列,查询条件中的各个列必须是组合索引中从最左边开始连续的列。如果我们仅仅按照第二列搜索,肯定无法走索引。

  1. WHERE 子句中的 OR

在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。只有一个条件列是索引列是没有意义的,只要有条件列不是索引列,就会进行全表扫描,所以需要两个条件都是索引列。

这篇关于什么情况下会造成索引失效?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/990019

相关文章

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

MySQL 添加索引5种方式示例详解(实用sql代码)

《MySQL添加索引5种方式示例详解(实用sql代码)》在MySQL数据库中添加索引可以帮助提高查询性能,尤其是在数据量大的表中,下面给大家分享MySQL添加索引5种方式示例详解(实用sql代码),... 在mysql数据库中添加索引可以帮助提高查询性能,尤其是在数据量大的表中。索引可以在创建表时定义,也可

宝塔安装的MySQL无法连接的情况及解决方案

《宝塔安装的MySQL无法连接的情况及解决方案》宝塔面板是一款流行的服务器管理工具,其中集成的MySQL数据库有时会出现连接问题,本文详细介绍两种最常见的MySQL连接错误:“1130-Hostisn... 目录一、错误 1130:Host ‘xxx.xxx.xxx.xxx’ is not allowed

Idea插件MybatisX失效的问题解决

《Idea插件MybatisX失效的问题解决》:本文主要介绍Idea插件MybatisX失效的问题解决,详细的介绍了4种问题的解决方法,具有一定的参考价值,感兴趣的可以了解一下... 目录一、重启idea或者卸载重装MyBATis插件(无需多言)二、检查.XML文件与.Java(该文件后缀Idea可能会隐藏

C++迭代器失效的避坑指南

《C++迭代器失效的避坑指南》在C++中,迭代器(iterator)是一种类似指针的对象,用于遍历STL容器(如vector、list、map等),迭代器失效是指在对容器进行某些操作后... 目录1. 什么是迭代器失效?2. 哪些操作会导致迭代器失效?2.1 vector 的插入操作(push_back,

MySQL索引失效问题及解决方案

《MySQL索引失效问题及解决方案》:本文主要介绍MySQL索引失效问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql索引失效一、概要二、常见的导致MpythonySQL索引失效的原因三、如何诊断MySQL索引失效四、如何解决MySQL索引失

C# foreach 循环中获取索引的实现方式

《C#foreach循环中获取索引的实现方式》:本文主要介绍C#foreach循环中获取索引的实现方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、手动维护索引变量二、LINQ Select + 元组解构三、扩展方法封装索引四、使用 for 循环替代

MySQL索引的优化之LIKE模糊查询功能实现

《MySQL索引的优化之LIKE模糊查询功能实现》:本文主要介绍MySQL索引的优化之LIKE模糊查询功能实现,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前缀匹配优化二、后缀匹配优化三、中间匹配优化四、覆盖索引优化五、减少查询范围六、避免通配符开头七、使用外部搜索引擎八、分

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

查看Oracle数据库中UNDO表空间的使用情况(最新推荐)

《查看Oracle数据库中UNDO表空间的使用情况(最新推荐)》Oracle数据库中查看UNDO表空间使用情况的4种方法:DBA_TABLESPACES和DBA_DATA_FILES提供基本信息,V$... 目录1. 通过 DBjavascriptA_TABLESPACES 和 DBA_DATA_FILES