当前位置:

首页 > 编程开发 > MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

结论具体案例下文有详尽描述不适合建立索引的场景:数据量比较小的表不建议建立索引有大量重复数据的字段上不建议建立索引(类似:性别字段)需要进行频繁更新的表不建议建立索引where、groupby、orderby后面的没有使用到的字段不建立索引不要定义冗余索引索引失效的场景:过滤条件使用不等于(!=、)过滤条件使用isnotnull在索引字段上使用函数或进行计算在使用联合索引的时候,需要满足“最佳左前缀法则”,否则失效当使用了类型转换也会导致索引失效在使用范围查询的时候,联合索引的部分字段失效(whereag

本文目录

    结论

    具体案例下文有详尽描述

    不适合建立索引的场景:

    • 数据量比较小的表不建议建立索引

    • 有大量重复数据的字段上不建议建立索引(类似:性别字段)

    • 需要进行频繁更新的表不建议建立索引

    • where、group by、order by后面的没有使用到的字段不建立索引

    • 不要定义冗余索引

    索引失效的场景:

    • 过滤条件使用不等于(!=、<>)

    • 过滤条件使用is not null

    • 在索引字段上使用函数或进行计算

    • 在使用联合索引的时候,需要满足“最佳左前缀法则”,否则失效

    • 当使用了类型转换也会导致索引失效

    • 在使用范围查询的时候,联合索引的部分字段失效(where age >18)

    • 在like字段中,如果是以%开头,索引失效(where name like ‘%abc’)

    • 在使用or进行查询的时候,or前后出现非索引字段,索引失效

    • 表和库的字符集不一致,回导致索引失效

    知识点:

    • 每张表的索引不建议超过6个(占用空间、降低表更新速度)

    • 最终到底是否使用索引还是优化器进行决定的

    • 优化器会根据数据量、数据库版本、数据选择读进行查询代价的比较,从而决定是否使用索引

    • 建立索引的时候将需要范围匹配的字段建立在索引的尾部,避免失效

    • 在建立表的时候将字段设置为not null同时设置默认值,当需要查找没有值的记录的时候就可以使用where xxx = 默认值,放置使用is not null导致索引失效

    • 页面搜索的时候严谨左模糊或者全模糊(like ‘%abc’)

    • 对于过滤性较好的字段建立在联合索引的前面,这样就可以优先过滤比较多的数据

    不建议建立索引的场景

    场景一:数据少的表

    当数据比较少的时候,索引的优势就不明显了,因为数据库的存储引擎也是非常快的,相较于需要查询索引在进行回表操作,可能直接查询的性能会更高一些,所以数据相对较少的表不建议建立索引

    场景二:有大量重复数据的字段

    类似于性别字段,只有“男”和“女”两个不同的值,所以索引一半的数据是“男”一半的数据是“女”,那么建立索引并不能进行快速的查询等,所以不建议在有大量重复数据的列上建立索引

    场景三:频繁更新的表(update/delete/insert)

    因为表中更新数据的时候,索引也是需要进行对应的维护的,如果一个表近期需要频繁的进行增删改操作,那么就需要耗费大量的时间去维护索引,不建议建立索引,可以在需要进行频繁的更新操作的时候将索引删除,更新完毕之后重建索引

    场景四:没有使用的字段(where/group by/order by)

    不是where/group by/order by后面的字段没有必要建立索引,因为不会使用到该索引

    场景五:不要定义冗余索引

    create index username_password_address on xiao(username,password,address);
    -- 如果建立了第一个索引,那么就没有必要建立第二个索引
    create index username on xiao (username);
    --第二个索引就是冗余索引,因为第一个已经是先根据username排序的索引
    --也就是第二个索引的功能完全可以由第一个索引实现

    这里因为username作为第一个联合索引的第一个字段,所以索引就是按照username进行排序,在username相同的情况下按照password、address排序,所以也就是实现了单独拿username列作为索引的功能,即第二个索引就是多余的

    索引失效的场景

    场景一:在建立索引的字段上进行运算(函数等),导致索引失效

    这里首先是给age创建了索引,在第一次查询过程中使用了age索引,但是第二次key值为null(索引失效),导致索引失效的原因在于第二次查询的时候where后面对age进行了计算,计算机并不知道执行的是什么计算所以会将age+1计算后与1比较,索引失效

    类似于在字段上使用函数concat()等都会导致索引失效

    MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

    场景二:使用不等于(where age != 18)

    当使用等值运算,那么是可以在索引中进行查找的,但是如果是不等于,那么则需要遍历所有数据,所以所失效

    explain select * from xiaoyuanhao where age = 18;
    explain select * from xiaoyuanhao where age != 18;
    --这里是在age字段上建立了普通索引,第二个查询时候索引失效

    场景三:使用is not null索引失效

    与不等于一样,如果使用的是is not null,那么就需要进行全部数据的遍历操作,索引失效,但是如果使用的是is null那么依旧是可以使用索引的

    --这里是在age字段上建立了普通索引,第二个查询时候索引失效
    explain select * from xiaoyuanhao where age is null;
    --可以正常使用索引
    explain select * from xiaoyuanhao where age is not null;
    --索引失效

    场景四:在使用联合索引的时候没有遵循最佳左前缀法则

    CREATE INDEX age_classid_name ON student(age,classId,NAME);
    EXPLAIN SELECT * FROM student WHERE classId = 30 AND NAME = 'xiaoyuanhao';
    -- 因为没有使用age字段,所以没有准许最佳左前缀原则,索引失效

    MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

    从这里可以看出是没有使用索引的(key = null),因为创建的索引是先按照age进行排序,在age相同的情况下按照classId和name排序,如果在查询的时候需要直接按照classId进行排序查找,那么就无法使用该索引,即索引失效。

    如果需要使用使用索引,那么就一定需要到联合索引的第一个字段age,案例如下

    EXPLAIN SELECT * FROM student WHERE age = 10 AND NAME = 'xiaoyuanhao';
    EXPLAIN SELECT * FROM student WHERE age = 10 AND classId = 33 AND NAME = 'xiaoyuanhao';
    --两者都是使用age字段索引,所以索引有效

    MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

    MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

    场景五:类型转换导致索引失效

    CREATE INDEX NAME ON student(NAME);
    -- 这里的name字段是varchar类型
    EXPLAIN SELECT * FROM student WHERE NAME = 'xiao';
    -- 本次查询是可以使用索引的,因为类型都是一致的,都是字符串
    EXPLAIN SELECT * FROM student WHERE NAME = 123;
    -- 本次查询则无法使用索引,因为是将数字类型123转换为字符类型

    没有发生类型转换,使用索引key = name

    MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

    发生了类型转换,无法使用索引kye = null,索引失效

    MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

    使用索引的时候一定需要保证数据类型是一致的,否则系统就需要进行转换,那么就无法使用索引

    场景六:使用范围查询导致联合索引其他字段失效

    create index age_classId_name on student (age,classId,name);
    EXPLAIN SELECT * FROM student WHERE age = 10 AND classId > 20 AND NAME = 'xiaoyuanhao';
    -- 这里只能使用age,classId,索引的前两个字段
    EXPLAIN SELECT * FROM student WHERE age = 10 AND classId = 20 AND NAME = 'xiaoyuanhao';
    -- 这里可以使用完整的索引,因为都是等值连接

    在classId字段上使用范围查询,导致name字段失效,有效索引长度为63

    MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

    使用的都是等值匹配,整个索引皆可用,有效索引长度为73

    MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

    也就是在对于联合索引来说,如果在使用的时候是等值匹配,那么就可以重复的利用索引,如果不是等值匹配,那么该字段也是可以使用索引的,但是该字段右边的字段就将失效

    建议在建立索引的时候将需要范围匹配的字段建立在索引的最后面

    场景七:在使用like的时候,如果以%开头导致索引失效

    EXPLAIN SELECT * FROM student WHERE NAME LIKE 'abc%';
    -- 可以正常使用索引
    EXPLAIN SELECT * FROM student WHERE NAME LIKE '%abc';
    -- 这里在like中,%在前面无法使用索引

    key = name,使用了该索引,索引有效

    MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

    key = null,索引失效

    MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

    因为建立的索引实际上是按照整个字符串的从第一个开始进行比较排序的,所以在使用like的时候,也只能够重现进行比较,如果使用的是’%abc’,那么查询的就是以abc结尾的数据,无法使用索引

    场景八:or前后出现非索引字段,索引失效

    -- 该表中只有name字段上的索引
    CREATE INDEX NAME ON student(NAME);
    EXPLAIN SELECT * FROM student WHERE NAME = 'xiao';
    -- 这里是可以使用name索引的
    EXPLAIN SELECT * FROM student WHERE NAME = 'xiao' OR classId = 1001;
    -- 这个则无法使用索引,进行的是全表扫描

    key = null,无法使用索引,or条件中出现非索引字段

    MySQL中不适合创建索引和可能导致索引失效的情况有哪些?

    因为如果name不等于’xiao’的时候那么就会继续判断classId是否等于1001,那么实际上还是会进行全表扫描,所以索引失效(也就是进行name判断的时候可以使用索引,但是在判断classId的时候又要全表扫描,那么优化器就直接进行全表扫描),但是如果or前后的字段都有索引了,那么就就会使用索引

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 MySQL
    相关文章 更多
    navicat导入数据库步骤详解及常见问题处理教程
    navicat导入数据库步骤详解及常见问题处理教程

    详解Navicat导入数据库的标准步骤,涵盖SQL脚本执行与CSV数据导入两种核心场景。针对导入过程中常见的字符集乱码、主键冲突及外键约束错误,提供具体的设置方法与修复建议,确保数据迁移准确无误。

    SQL主键约束和唯一约束有什么区别
    SQL主键约束和唯一约束有什么区别

    深入理解SQL PRIMARY KEY与UNIQUE约束的区别。文章从行标识与重复限制的目标出发,详解主键的非空特性、外键引用角色以及多数据库对NULL值的处理差异。结合users表实战示例,指导开发者如何根据字段稳定性与业务语义合理选择约束类型,避免设计误区。

    SQL约束有哪些类型及作用
    SQL约束有哪些类型及作用

    刚开始设计关系型数据库?了解PRIMARY KEY、FOREIGN KEY、UNIQUE、NOT NULL、CHECK、DEFAULT等约束的作用、语法和排错方法。本文以PostgreSQL语法为主,结合用户订单场景,清晰展示如何防止脏数据并处理常见约束冲突。

    SQL游标常见错误排查:死锁与资源未释放问题
    SQL游标常见错误排查:死锁与资源未释放问题

    深入解析SQL游标导致的死锁与资源未释放问题。通过PostgreSQL与MySQL语法对比,展示如何识别长事务持锁、分析锁等待链,并提供短事务提交、异常清理及批量处理的最佳实践,确保数据库连接与锁资源及时释放。

    SQL中怎么创建和删除约束
    SQL中怎么创建和删除约束

    后端开发者在维护数据库时,常需对现有表添加主键、唯一或外键约束。若直接执行ADD CONSTRAINT,往往因存量数据不合规导致报错。本文详解操作前的数据清洗步骤、标准SQL语法及MySQL等特殊写法,帮助你在生产环境安全完成结构变更。

    SQL分组统计查询:GROUP BY与HAVING子句用法示例
    SQL分组统计查询:GROUP BY与HAVING子句用法示例

    针对 SQL 初学者的分组统计实战指南。深入解析 GROUP BY 分组机制、WHERE 与 HAVING 的执行时机差异,以及 COUNT 函数对 NULL 值的处理逻辑。通过具体代码示例演示如何正确筛选聚合结果,并排查因 JOIN 连接导致的统计数据异常,提升报表准确性。

    SQL Server与MySQL游标基本语法及完整代码示例
    SQL Server与MySQL游标基本语法及完整代码示例

    本文详细对比SQL Server和MySQL中游标的基本用法。从DECLARE声明到FETCH遍历,再到CLOSE关闭与DEALLOCATE/Handler清理,解析两者在语法结构、变量接收及异常处理上的核心差异。通过标准代码示例展示如何安全使用游标,避免资源泄漏,适用于需要进行数据库存储过程开发或跨平台迁移的开发者。

    SQL多表连接区别:INNER JOIN与LEFT JOIN的使用场景
    SQL多表连接区别:INNER JOIN与LEFT JOIN的使用场景

    深入解析SQL中INNER JOIN与LEFT JOIN的核心区别。通过users和orders表实例,展示匹配行保留与NULL补位机制,重点讲解ON与WHERE子句中放置右表过滤条件的不同后果,提供防止LEFT JOIN退化的实战技巧及行数异常排查步骤。

    SQL CHECK约束的用法与取值范围限制
    SQL CHECK约束的用法与取值范围限制

    深入理解 SQL CHECK 约束在 PostgreSQL、MySQL 等数据库中的实现差异。文章通过订单业务场景,讲解如何定义单列范围与多列逻辑约束,分析 NULL 值对布尔条件的影响,并提供修改已有表结构时的安全操作建议,帮助开发者构建更健壮的数据完整性防线。

    SQL外键约束怎么用及级联操作说明
    SQL外键约束怎么用及级联操作说明

    后端开发中,如何正确使用 SQL 外键约束来维护订单与明细表的关系?本文通过 PostgreSQL 示例,深入讲解外键的创建语法、插入顺序要求,以及 ON DELETE CASCADE、RESTRICT、SET NULL 等策略的实际影响与风险控制,助你构建健壮的数据库结构。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。