MySQL 索引失效详解

这篇具有很好参考价值的文章主要介绍了MySQL 索引失效详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

MySQL 索引失效详解

一、MySQL索引失效原因汇总

  1. 隐式的类型转换,索引失效
  2. 查询条件包含or,可能导致索引失效
  3. like通配符可能导致索引失效
  4. 查询条件不满足联合索引的最左匹配原则
  5. 在索引列上使用mysql的内置函数
  6. 对索引进行列运算(如,+、-、*、/)
  7. 索引字段上使用 (! = 或者< >),索引可能失效
  8. 索引字段上使用is null, is not null,索引可能失效
  9. 左右连接,关联的字段编码格式不一样
  10. 优化器选错了索引

二、MySQL索引失效原因分析

(1)隐式的类型转换,索引失效

如:普通索引userId是string,查询时用了where userId = 123;结果不走索引;如果给数字加上’',也就是说,传的是一个字符串呢,当然是走索引。
解释:为什么第一条语句未加单引号就不走索引了呢?这是因为不加单引号时,是字符串跟数字的比较,它们类型不匹配,
MySQL会做隐式的类型转换,把它们转换为浮点数再做比较。隐式的类型转换,索引会失效。

(2)查询条件包含or,可能导致索引失效

如:其中userId加了索引,但是age没有加索引的。我们使用了or,以下SQL是不走索引的,如下:select * from user where userId = ‘123’ or age = ‘18’;
解释:对于or+没有索引的age这种情况,假设它走了userId的索引,但是走到age查询条件时,它还得全表扫描,也就是需要三步过程:全表扫描+索引扫描+合并。
如果它一开始就走全表扫描,直接一遍扫描就完事。Mysql优化器出于效率与成本考虑,遇到or条件,让索引失效,看起来也合情合理嘛。
注意:如果or条件的列都加了索引,索引可能会走也可能不走,大家可以自己试一试哈。
但是平时大家使用的时候,还是要注意一下这个or,学会用explain分析。遇到不走索引的时候,考虑拆开两条SQL。

(3)like通配符可能导致索引失效

如:like查询以%开头,索引失效,如:select * from user where userId like ‘%123’;
like把%放后面,发现索引还是正常走的,如下:select * from user where userId like ‘123%’;
解释:并不是用了like通配符,索引一定会失效,而是like查询是以%开头,才会导致索引失效。
思考:既然like查询以%开头,会导致索引失效。我们如何优化呢?
1.使用覆盖索引;2.把%放后面

(4)查询条件不满足联合索引的最左匹配原则

MySQl建立联合索引时,会遵循最左前缀匹配的原则,即最左优先。在联合索引中,查询条件满足最左匹配原则时,索引才正常生效。
如果你建立一个(a,b,c)的联合索引,相当于建立了(a)、(a,b)、(a,b,c)三个索引。
前提:联合索引(userId,name)
如:select * from user where name =‘张三’;因为查询条件列name不是联合索引idx_userid_name中的第一个列,索引不生效;
select * from user where userId =‘123’;查询条件满足最左匹配原则时,索引才正常生效。

(5)在索引列上使用mysql的内置函数

如:给login_time加了索引,但是因为使用了mysql的内置函数Date_ADD(),索引直接失效,
select * from user where DATE_ADD(login_time,INTERVAL 1 DAY)=‘2022-05-22 00:00:00’;
思考:一般这种情况怎么优化呢?可以把内置函数的逻辑转移到右边,如下:
select * from user where login_time = DATE_ADD(‘2022-05-22 00:00:00’,INTERVAL 1 DAY);

(6)对索引进行列运算(如,+、-、*、/)

如:给age加了索引,但是因为它进行运算,索引直接失效,如:select * from user where age -1 = 10;
所以不可以对索引列进行运算,可以在代码处理好,再传参进去。

(7)索引字段上使用 (! = 或者< >),索引可能失效

如:给age加了索引,但是使用了!= 或者< >,not in这些时,索引如同虚设。如下:select * from user where age != 18;
解释:其实这个也是跟mySQL优化器有关,如果优化器觉得即使走了索引,还是需要扫描很多很多行的话,它觉得不划算,不如直接不走索引。
平时我们用!= 或者< >,not in的时候,留点心眼哈。

(8)索引字段上使用is null, is not null,索引可能失效

如:给单个name字段加上索引,并查询name为非空的语句,其实会走索引的,如下:select * from user where name is not null;
单个card字段加上索引,并查询card为非空的语句,其实会走索引的,如下:select * from user where card is not null;
注意:但是它两用or连接起来,索引就失效了,如下:select * from user where name is not null or card is not null;
解释:很多时候,也是因为数据量问题,导致了MySQL优化器放弃走索引。同时,平时我们用explain分析SQL的时候,如果type=range,要注意一下哈,
因为这个可能因为数据量问题,导致索引无效。

(9)左右连接,关联的字段编码格式不一样

前提:user表的name字段编码是utf8mb4,而user_job表的name字段编码为utf8。
如:执行左外连接查询,user_job表还是走全表扫描,如下:select * from user a join user_job b on a.name = b.name;
如果把它们的name字段改为编码一致,相同的SQL,还是会走索引。

(10)优化器选错了索引

解释:MySQL 中一张表是可以支持多个索引的。你写SQL语句的时候,没有主动指定使用哪个索引的话,用哪个索引是由MySQL来确定的。
思考:我们日常开发中,不断地删除历史数据和新增数据的场景,有可能会导致MySQL选错索引。那么有哪些解决方案呢?
1.使用force index 强行选择某个索引
2.修改你的SQl,引导它使用我们期望的索引
3.优化你的业务逻辑
4.优化你的索引,新建一个更合适的索引,或者删除误用的索引。

关注林哥,持续更新哦!!!★,°:.☆( ̄▽ ̄)/$:.°★ 。文章来源地址https://www.toymoban.com/news/detail-430954.html

到了这里,关于MySQL 索引失效详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Mysql索引失效的场景分析

    前言: 日常使用Mysql做一些业务时,发现很慢,跟踪日志返现是有慢查询语句,于是使用explain查看执行计划发现是没有使用到索引,一般这些情况都不是java框架导致的,一般框架里都会根据主键或者指定的条件去做简单的查询,复杂的查询都是通过sql原生写法来实现的,这

    2023年04月20日
    浏览(44)
  • MySQL索引失效的七大场景

    模型数或运算快 这里我们以MySQL自带的world数据库中的country表为例。 向name列添加索引 查看country表索引 测试like完全匹配 可以看到type级别是index。索引失效。 在 MySQL 中,使用 EXPLAIN 语句可以查看查询语句的执行计划,了解 MySQL 如何执行查询。其中,EXPLAIN 语句的结果集中的

    2023年04月22日
    浏览(51)
  • 第20章:MySQL索引失效案例

    1. 全值匹配我最爱 当SQL查询 创建3个索引 当前优化器会选择跟where条件匹配最高的idx_age_classid_name索引,直接查询出对应的主键值然后回表查询,此时的效率最高。所以部分索引失效,因为使用的部分索引,会查询多个主键值还需要回表继续判断,效率低。 2. 最佳左前缀规则

    2024年02月11日
    浏览(40)
  • MySQL索引3——Explain关键字和索引优化(SQL提示、索引失效、索引使用规则)

    目录 Explain 索引性能分析 Id ——select的查询序列号 Select_type——select查询的类型 Table——表名称 Type——select的连接类型 Possible_key ——显示可能应用在这张表的索引 Key——实际用到的索引 Key_len——实际索引使用到的字节数 Ref    ——索引命中的列或常量 Rows——预

    2024年02月14日
    浏览(57)
  • mysql : name like “%name“; 索引一定失效吗?

    场景如下: MySQL版本如下: 表结构如下: 索引结构如下: 查询语句以及执行计划如下: 第一条查询语句: select name from em where name like ‘%b’; 可以发现使用了name 字段创建的索引 第二条查询语句: select id from em where name like ‘%b’; 第三条查询语句: select * from em where name l

    2024年02月03日
    浏览(40)
  • 面试官:讲讲MySql索引失效的几种情况

    拓展:Alibaba《Java开发手册》 【强制】页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。 注意: 当数据库中的数据的索引列的 NULL值达到比较高的比例的时候 ,即使在IS NOT NULL 的情况下 MySQL的查询优化器会选择使用索引, 此时type的值是range(范围查询) 测试

    2024年02月11日
    浏览(38)
  • MySQL索引3——Explain关键字和索引使用规则(SQL提示、索引失效、最左前缀法则)

    目录 Explain 索引性能分析 Id ——select的查询序列号 Select_type——select查询的类型 Table——表名称 Type——select的连接类型 Possible_key ——显示可能应用在这张表的索引 Key——实际用到的索引 Key_len——实际索引使用到的字节数 Ref    ——索引命中的列或常量 Rows——预

    2024年02月14日
    浏览(44)
  • 【MySQL】SQL索引失效的几种场景及优化

    MySQL中提高性能的一个最有效的方式是对数据表设计合理的索引。索引提供了高效访问数据的方法,并且加快查询的速度, 因此索引对查询的速度有着至关重要的影响。 使用索引可以快速地定位表中的某条记录,从而提高数据库查询的速度,提高数据库的性能。如果查询时没

    2024年02月13日
    浏览(39)
  • Mysql进阶优化篇02——索引失效的10种情况及原理

    前 言 🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端 🍌 专栏简介:mysql基础、进阶,主要讲解mysql数据库sql刷题、进阶知识,包括索引、数据库调优、分库分表等 🌰 文章简介:本文将介绍索引失效的10种情况及原理,绝对不需要死记硬背,建议收

    2024年02月02日
    浏览(42)
  • MySQL中IN的取值范围较大时会导致索引失效

    结论:IN肯定会走索引,但是当IN的取值范围较大时会导致 索引失效,走全表扫描 navicat可视化工具使用explain函数查看sql执行信息 1.1 场景1:当IN中的取值只有一个主键时 我们只需要注意一个最重要的type 的信息很明显的提现是否用到索引: type结果值从好到坏依次是: syste

    2024年02月15日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包