导读:本期聚焦于小伙伴创作的《MySQL如何优化查询性能?深入剖析索引和执行计划的优化技巧》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《MySQL如何优化查询性能?深入剖析索引和执行计划的优化技巧》有用,将其分享出去将是对创作者最好的鼓励。

MySQL作为最常用的关系型数据库之一,查询性能的优劣直接影响上层业务的运行效率。当单表数据量达到百万甚至千万级别时,没有经过优化的查询可能会出现全表扫描,导致响应时间从毫秒级飙升到秒级甚至更长。优化查询性能的核心方向主要围绕索引设计和执行计划分析展开,二者结合能从根源上解决大部分查询慢的问题。

MySQL如何优化查询性能?深入剖析索引和执行计划的优化技巧

一、索引优化核心技巧

1.1 索引设计的基本原则

索引的本质是排好序的快速查找数据结构,合理设计索引需要遵循以下原则:

  • 优先为经常作为查询条件、排序条件、分组条件的字段创建索引
  • 尽量使用覆盖索引,避免回表查询,减少IO消耗
  • 控制索引数量,单表索引建议不超过5个,避免写入时索引维护成本过高
  • 选择区分度高的字段作为索引,区分度计算公式:count(distinct 列名)/count(*),值越接近1区分度越高
  • 避免对频繁更新的字段创建索引,更新字段时需要同步更新索引,增加开销

1.2 联合索引的最左前缀原则

联合索引是指多个字段组合的索引,使用时需要遵循最左前缀原则,即查询条件必须包含联合索引最左边的字段,索引才会生效。例如创建联合索引(a,b,c),以下查询可以使用索引:

-- 可以使用索引的查询
SELECT * FROM table WHERE a = 1;
SELECT * FROM table WHERE a = 1 AND b = 2;
SELECT * FROM table WHERE a = 1 AND b = 2 AND c = 3;
SELECT * FROM table WHERE a = 1 AND c = 3; -- 仅使用a字段的索引部分

-- 无法使用索引的查询
SELECT * FROM table WHERE b = 2;
SELECT * FROM table WHERE b = 2 AND c = 3;

1.3 索引失效的常见场景

即使创建了索引,以下场景也可能导致索引失效,查询走全表扫描:

  • 查询条件中对索引字段使用函数或表达式计算,例如WHERE YEAR(create_time) = 2023
  • 使用LIKE以通配符开头,例如WHERE name LIKE '%张三'
  • 查询条件中使用OR,且OR两边的字段不全有索引
  • 字符串类型的索引字段查询时未加单引号,例如WHERE phone = 13800138000(phone为varchar类型)
  • 查询优化器判断全表扫描比走索引更快,例如查询返回表中大部分数据

二、执行计划解读与优化

2.1 如何查看执行计划

在查询语句前加上EXPLAIN关键字即可查看该查询的执行计划,语法如下:

EXPLAIN SELECT * FROM user WHERE age > 18 AND city = '北京';

执行后会返回多个字段,核心字段的含义如下:

字段名含义
id查询的序列号,id越大越先执行,id相同则从上到下执行
select_type查询类型,常见值有SIMPLE(简单查询)、PRIMARY(主查询)、SUBQUERY(子查询)等
table当前查询涉及的表名
type访问类型,性能从好到坏依次为:system > const > eq_ref > ref > range > index > ALL
possible_keys查询可能使用的索引
key查询实际使用的索引,为NULL表示未使用索引
rows预估需要扫描的行数,值越小越好
Extra额外信息,常见值有Using index(覆盖索引)、Using where(需要回表过滤)、Using filesort(需要额外排序)、Using temporary(使用临时表)

2.2 基于执行计划的优化案例

假设存在用户表user,结构如下:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `city` varchar(50) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_age_city` (`age`,`city`) -- 联合索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

执行以下查询并查看执行计划:

EXPLAIN SELECT * FROM user WHERE city = '上海' AND age > 20;

此时执行计划中key为NULL,type为ALL,说明没有使用索引,原因是查询条件没有遵循联合索引的最左前缀原则,把age放在前面即可使用索引:

EXPLAIN SELECT * FROM user WHERE age > 20 AND city = '上海';

优化后执行计划中keyidx_age_citytyperange,扫描行数大幅减少,查询性能得到提升。

2.3 优化Using filesort和Using temporary

Using filesort表示查询需要的排序无法利用索引完成,需要额外进行排序操作,Using temporary表示查询需要创建临时表来存储中间结果,二者都会严重影响查询性能。

优化方案:如果查询有排序需求,尽量让排序字段和查询条件的索引字段匹配,例如联合索引(a,b),查询WHERE a = 1 ORDER BY b可以利用索引排序,不会出现Using filesort。如果查询需要分组,尽量让分组字段使用索引,避免产生临时表。

三、综合优化实践

实际业务中优化查询性能通常需要结合索引和执行计划共同分析,步骤如下:

  1. 开启慢查询日志,记录执行时间超过阈值的SQL语句
  2. 对慢查询语句使用EXPLAIN查看执行计划,定位问题点
  3. 检查是否有合适的索引,没有则根据查询条件创建合理的索引
  4. 检查索引是否失效,调整查询条件写法避免索引失效
  5. 优化查询语句本身,避免查询不必要的字段,减少返回数据量
  6. 再次查看执行计划,确认优化效果,直到查询性能满足要求

通过以上步骤,大部分查询性能问题都可以得到有效解决,同时要注意定期分析业务查询的变化,及时调整索引策略,避免索引冗余或者索引缺失的情况。

MySQL索引优化执行计划查询性能SQL优化修改时间:2026-07-15 14:03:15

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