首页 > 数据库 >探索MySQL的InnoDB索引失效

探索MySQL的InnoDB索引失效

时间:2024-10-06 17:12:20浏览次数:7  
标签:MySQL 查询 运算符 索引 InnoDB 使用 失效

MySQL 8+

InnoDB

-

 

序章

索引失效,发生在 已经建立索引,但是,查询(SELECT)时没有用到建立的(预期会用到)索引的情况下。

失效原因有两个方面:

1、建立索引的方式错误

需要弄清楚 字段的 #区分度(极其重要) 这个概念。选择 区分度高 的建立索引。

2、某些SELECT语句不支持 使用索引

注意,除了索引失效,导致 慢查询 的另一个重要原因是——没有建立索引,没有在 创建表 的时候第一时间建立索引。

 

本文探索 MySQL使用时常见的索引失效情况,做个汇总。

 

通义千问

问题:InnoDB:索引失效会在什么情况下发生?

回答:

在 InnoDB 存储引擎中,索引失效 是指 查询优化器 决定不使用已存在的索引,而是 选择全表扫描 或 其他方式来执行查询。

以下是一些常见的索引失效情况:

1)选择性低的索引

原因:如果索引的选择性很低(即索引列的重复值很多),MySQL 可能会选择不使用该索引,因为全表扫描可能更快。

#区分度

2)使用 OR 运算符

原因:当查询条件中包含 OR 运算符时,如果 OR 连接的条件不能使用同一个索引,MySQL 可能会选择不使用索引。

3)使用函数或表达式

原因:在索引列上使用函数或表达式会导致索引失效,因为 MySQL 无法直接使用索引进行查找。

4)使用 LIKE 模糊查询

原因:如果 LIKE 模糊查询的前缀是通配符(如 %),索引将失效。

5)数据类型不匹配

原因:如果查询条件中的数据类型与索引列的数据类型不匹配,MySQL 可能会选择不使用索引。

6)使用 NOT 运算符

原因:使用 NOT 运算符(如 != 或 <>)时,MySQL 可能会选择不使用索引,因为这些运算符通常会导致全表扫描。

7)使用 IN 运算符

原因:如果 IN 运算符中的值列表非常大,MySQL 可能会选择不使用索引。

8)索引列上有大量 NULL 值

原因:如果索引列中有大量 NULL 值,MySQL 可能会选择不使用该索引。

9)复合索引的使用不当

原因:如果复合索引的前导列没有出现在查询条件中,MySQL 可能会选择不使用该复合索引。

10)表统计信息不准确

原因:如果表的统计信息不准确,MySQL 的查询优化器可能会做出错误的决策,导致索引失效。

11)使用 LIMIT 时

原因:在某些情况下,使用 LIMIT 时,MySQL 可能会选择不使用索引,特别是当 LIMIT 的偏移量很大时。

12)使用 JOIN 时

原因:在复杂的 JOIN 查询中,如果 JOIN 条件不使用索引,MySQL 可能会选择不使用索引。

 

解决方法

1、优化查询条件:确保查询条件尽可能精确,避免使用函数、表达式和通配符。
2、使用合适的索引:为查询条件中的列创建合适的索引,特别是复合索引。
3、定期更新统计信息:使用 ANALYZE TABLE 命令定期更新表的统计信息。
4、避免使用 SELECT *:只选择需要的列,减少数据传输量。
5、使用 EXPLAIN 分析查询:使用 EXPLAIN 命令分析查询计划,确保索引被正确使用。

 

注,大家可以自行去提问。

 

参考资料#2

补充了2条:

13)数据表过度索引:太多

文中提到,索引太多,可能导致 查询优化器 选择错乱。

14)数据表过度庞大

文中提到,数据表太大时,索引的效果减弱了。

文中提到,可以使用 分区(PARTITION BY)、分片(ShardingSphere 等工具) 解决该问题。

或许,还有 分库,还有 使用 其它大数据存储工具。

 

小结

基本的 索引失效 大概就这些了,足够平时开发使用了。

 

进一步探索:TODO

1、分区、分表、分库 的索引如何建立?

2、MySQL 的 一些集群方案中怎么建立索引?这涉及到 大数据方面使用 MySQL 了吧?不太懂。

 

---END---

 

本文链接:

https://www.cnblogs.com/luo630/p/18448905

 

参考资料

1、通义千问

2、MySQL索引失效及避免策略:优化查询性能的关键

作者:糜终

2024-09-30

https://developer.aliyun.com/article/1615655

3、

 

ben发布于博客园

ben发布于博客园

 

标签:MySQL,查询,运算符,索引,InnoDB,使用,失效
From: https://www.cnblogs.com/luo630/p/18448905

相关文章

  • zoomeye类似搜索引擎和子域名搜索
    与zoomeye类似的搜索引擎[fofa][网络空间测绘,网络空间安全搜索引擎,网络空间搜索引擎,安全态势感知-FOFA网络空间测绘系统](https://fofa.info/)[Shodan][https://www.shodan.io](https://www.shodan.io/)[Censys][https://search.censys.io](https://search.censys.io/)子......
  • MySQL单表存多大的数据量比较合适
    前言经常使用MySQL数据库的小伙伴都知道,当单表数据量达到一定的规模以后,查询性能就会显著降低。因此,当单表数据量过大时,我们往往要考虑进行分库分表。那么如何计算单表存储多大的数据量合适?当单表数据达到多大的规模时,我们才要进行分库分表呢?MySQL存储方式首先我们要先了解一下......
  • 【2024计算机毕业设计】基于jsp+mysql+Spring+mybatis的SSM药品进货销售仓储信息管理
    运行环境:最好是javajdk1.8,我在这个平台上运行的。其他版本理论上也可以。IDE环境:Eclipse,Myeclipse,IDEA或者SpringToolSuite都可以,如果编译器的版本太低,需要升级下编译器,不要弄太低的版本tomcat服务器环境:Tomcat7.x,8.x,9.x版本均可操作系统环境:WindowsXP/7......
  • [MySQL]为什么大厂选择读已提交
    为什么读已提交的并发性更好在数据库中,锁的时间和范围是影响并发性的重要因素。已提交读(ReadCommitted)隔离级别与可重复读(RepeatableRead)的主要区别就在于它们在读取数据时对锁的使用方式不同。让我们详细看看为什么已提交读的锁的时间和范围更小。1.已提交读(ReadCommitte......
  • 重建帝国cms数据索引表,用于ecms_news_index表损坏丢失或者错误
    当帝国CMS的 ecms_news_index 表损坏或丢失时,可以通过以下步骤重建数据索引表。这些操作需要在数据库中执行,请确保在执行前备份所有相关数据。重建 ecms_news_index 表步骤1:创建临时表 ecms_newstempsql CREATETABLE[!db.pre!]ecms_newstempAS(SELECTid,c......
  • 本地环境PHP帝国备份王备份报错mysql_escape_string(): This function is
    在使用帝国备份王进行备份和恢复时,如果遇到PHP5.5环境下的报错,通常是因为一些旧的MySQL函数已经被弃用或移除。具体来说,mysql_escape_string 函数在PHP5.5中已经被废弃,应该使用 mysql_real_escape_string 替代。解决方案定位问题文件:找到 function.php 文件的位置。......
  • DBeaver 连接 mysql 报错:Public Key Retrieval is not allowed
    前言DBeaver连接mysql报错:PublicKeyRetrievalisnotallowed遇到"PublicKeyRetrievalisnotallowed"错误时,通常意味着你正在使用的身份验证方法需要加密连接,但是没有正确地配置客户端或服务器来支持这种加密。解决第一种可以在连接字符串中添加 allowPublicKey......
  • mysql 连接失败:message from server: "Host 'xx.xxx' is not allowed to connect to t
    前言mysql连接失败:messagefromserver:"Host'192.168.xx.xxx'isnotallowedtoconnecttothisMySQLserver"解决错误信息表明你尝试从IP地址192.168.xx.xxx连接到MySQL服务器,但是该IP地址没有被授权连接权限。为了解决这个问题,你需要确保你的MySQL用户权......
  • Java日总结24-10-4:MySQL语法-DML&DQL
    一、DML操作数据---添加&修改&删除添加数据:给出我的实例:修改数据:我的修改实例:!注意:修改时如果update语句不加where条件,则会把表中所有数据都修改了!删除数据:给出我的删除实例:!注意:删除时如果语句不加where条件,则会把表中所有数据都删除。以上为DML对表的增删改操作!二......
  • MySQL 中的 LAST_INSERT_ID()函数详解
    在MySQL数据库中,LAST_INSERT_ID()是一个非常有用的函数。它可以帮助我们获取最近一次插入操作所生成的自增ID值。本文将详细解释MySQL中的LAST_INSERT_ID()函数及其用途。一、函数介绍LAST_INSERT_ID()是MySQL中的一个内置函数,它返回最近一次插入操作所生成的自增ID值......