导读:本期聚焦于小伙伴创作的《MySQL组合索引为何失效?SELECT *查询为何会阻碍索引的使用?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《MySQL组合索引为何失效?SELECT *查询为何会阻碍索引的使用?》有用,将其分享出去将是对创作者最好的鼓励。

在MySQL数据库的实际使用中,组合索引是常见的优化手段,但不少开发者会遇到组合索引不生效的情况,同时SELECT *查询也经常被提及会影响索引的使用效率,这两个问题本质上都和MySQL的索引执行机制有关。

MySQL组合索引为何失效?SELECT *查询为何会阻碍索引的使用?

组合索引的生效规则

组合索引是指基于表中多个字段创建的索引,它的生效核心遵循最左前缀原则,也就是索引会按照创建时的字段顺序依次生效,只有查询条件中包含最左前缀的字段时,索引才会被使用。

假设我们创建如下组合索引:

-- 创建用户表
CREATE TABLE user (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50),
    age INT,
    city VARCHAR(50),
    INDEX idx_name_age_city (name, age, city)
);

上述组合索引的字段顺序是name、age、city,以下是几种常见的索引生效和失效场景:

查询条件索引是否生效说明
WHERE name = '张三'命中最左前缀字段name
WHERE name = '张三' AND age = 20命中name和age两个前缀字段
WHERE age = 20缺少最左前缀字段name
WHERE name = '张三' AND city = '北京'是(部分生效)只命中name字段,city无法使用索引

组合索引失效的其他常见场景

除了不满足最左前缀原则,以下情况也会导致组合索引失效:

  • 查询条件中对索引字段使用函数或运算,比如WHERE YEAR(create_time) = 2023,会导致索引失效
  • 查询条件中使用不等于、IS NULL、IS NOT NULL,比如WHERE name != '张三',可能导致索引失效
  • 查询条件中使用LIKE以通配符开头,比如WHERE name LIKE '%三',索引无法生效
  • 查询条件中字段类型不匹配,比如name是字符串类型,查询时写成WHERE name = 123,会发生隐式转换导致索引失效

SELECT *查询为何会阻碍索引使用

SELECT *查询会返回表中的所有字段,这会影响索引覆盖特性的发挥。索引覆盖是指查询的字段全部包含在索引中时,数据库不需要回表查询数据行,直接通过索引就能返回结果,大幅提升查询效率。

还是以上面的user表为例,组合索引idx_name_age_city包含了name、age、city三个字段,如果我们执行以下查询:

-- 查询字段都在索引中,走索引覆盖,不需要回表
SELECT name, age, city FROM user WHERE name = '张三';

-- 使用SELECT *,会返回id、name、age、city等所有字段,id不在索引中,需要回表查询
SELECT * FROM user WHERE name = '张三';

在上面的例子中,第一个查询的字段都在组合索引中,数据库可以直接从索引中获取所有需要的数据,不需要访问主键索引对应的数据行。而第二个查询使用SELECT *,需要返回id字段,id不在组合索引中,所以数据库在通过组合索引找到符合条件的记录后,还需要根据主键id去主键索引中查询完整的行数据,这个过程就是回表。

回表操作会增加IO开销,当查询的数据量较大时,会明显降低查询效率,相当于阻碍了索引的充分利用。另外如果查询需要的字段很少,使用SELECT *会额外传输不需要的字段数据,也会浪费网络带宽。

优化建议

针对组合索引失效和SELECT *的问题,我们可以采取以下优化措施:

  • 创建组合索引时,将查询频率高、区分度高的字段放在最左边,遵循最左前缀原则设计查询条件
  • 避免使用SELECT *,只查询需要的字段,尽量让查询字段覆盖在索引中,利用索引覆盖特性
  • 检查查询条件,避免出现函数运算、隐式转换、通配符开头等导致索引失效的写法
  • 可以通过EXPLAIN命令分析查询语句的执行计划,查看索引的使用情况,针对性调整查询或索引

以下是使用EXPLAIN分析查询的示例:

-- 分析SELECT *查询的执行计划
EXPLAIN SELECT * FROM user WHERE name = '张三';

-- 分析指定字段查询的执行计划
EXPLAIN SELECT name, age, city FROM user WHERE name = '张三';

执行EXPLAIN后,我们可以查看key字段是否使用了目标索引,Extra字段是否出现Using index(表示使用了索引覆盖),以此判断索引的使用是否符合预期。

MySQL组合索引索引失效SELECT_*查询优化修改时间:2026-06-24 04:03:27

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。