滴滴二面:MySQL执行计划中,Key有值,还是很慢怎么办?

文章内容收录到个人网站,方便阅读 :hardyfish.top/

如果 执行计划中 key 有值,type=index,但查询仍然很慢。

说明索引并没有按照预期优化查询性能,而是发生了全索引扫描(Index Full Scan)。

这种情况的核心问题可能出在索引使用方式或查询优化上。

如何正确分析 SQL 执行计划?

在 EXPLAIN 结果中,几个重要的字段:

字段 含义 重点
id 查询执行的步骤 越大表示执行顺序越靠后
type 访问类型 影响查询效率的关键
possible_keys 可能使用的索引 可供查询选择的索引
key 实际使用的索引 如果是 NULL,说明没用索引
rows 预计扫描行数 值越大说明查询性能越差
Extra 额外信息 是否 Using index 或 Using where; Using index

问题分析:type=index 代表什么?

如果 type=index,说明进行了全索引扫描(Index Full Scan),即遍历整个索引树,而不是通过索引加速查询。

这个情况类似于 全表扫描(type=ALL),只是扫描的是索引而非数据表。

示例:

sql 复制代码
EXPLAIN SELECT col1 FROM my_table WHERE col2 = 'xxx';

可能返回:

asciidoc 复制代码
+----+-------+---------------+----------+--------------------------+
| id | type  | possible_keys | key      | Extra                    |
+----+-------+---------------+----------+--------------------------+
|  1 | index | NULL          | idx_col2 | Using where; Using index |
+----+-------+---------------+----------+--------------------------+

在 Extra 中 出现 Using where; Using index,意味着:

SQL 确实用了索引 idx_col2(key 列)。

但查询仍然需要回表或扫描整个索引树。

可能的原因:索引未能高效筛选数据。

可能导致查询慢的原因

  1. 索引失效:没有满足最左前缀匹配

    • 复合索引 (a, b, c),如果 WHERE 仅 b, c,则索引失效。
    • 建议:调整查询,确保 WHERE 子句符合索引最左匹配原则。
  2. 索引筛选性差,导致大量数据扫描

    • 低选择性索引(如 status=1 这种大量重复值)会导致扫描大量行。
    • 优化:换更高区分度的列建立索引。
  3. 回表查询导致性能下降

    • EXTRA中如果出现Using where; Using index,意味着:

      • 查询需要回表(即索引不覆盖查询列)
    • 优化方案:创建覆盖索引,减少回表操作

      sql 复制代码
      -- 假设查询 `SELECT col1 FROM my_table WHERE col2 = 'xxx'`
      -- 现有索引 idx_col2(col2)
      -- 改进:创建联合索引 (col2, col1) 避免回表
      CREATE INDEX idx_col2_col1 ON my_table (col2, col1);
  4. 使用 LIKE '%xx' 或者 函数操作列,导致索引失效

    • WHERE UPPER(name) = 'JOHN' 使得 name 索引失效
    • 解决方案:避免对索引列使用函数,或者考虑创建函数索引

解决方案

问题 解决方案
索引未匹配 WHERE 调整 SQL 确保最左匹配
索引选择性差 选择更具区分度的索引
需要回表查询 用覆盖索引优化
LIKE '%xx' 导致全索引扫描 改进索引或考虑全文索引(FULLTEXT)

总结

当 key 有值但查询仍然很慢:

重点关注 type 和 Extra 字段,看是否 Using where; Using index

可能是全索引扫描 (type=index)导致的,意味着索引没加速查询

检查索引是否最左匹配、是否需要回表、索引选择性是否合理

尝试优化 SQL 结构 ,或创建覆盖索引,减少回表扫描

相关推荐
❀͜͡傀儡师4 分钟前
Spring AI 集成 TypeSafe:用判断模型处理工单分流与链路决策
java·人工智能·spring
bro_Java6667 分钟前
《栈与队列:数据结构的“双生花”》
java·数据结构·编辑器
花开路口9 分钟前
线程安全完全指南:从 Java 到 Kotlin,一文吃透并发编程
java·kotlin
她说..15 分钟前
IntelliJ IDEA 快捷键速查表(Mac 版)
java·macos·intellij-idea
EatFan24 分钟前
JunoYi 框架实践:Spring Boot 项目为什么拆成 framework、module、server 三层?
java·spring boot·后端·framework·module·模块化·junoyi
汉堡大王952729 分钟前
一张图三句需求,我用 Trae Work 做了一块能看日出日落和月相的天文机械表
前端·后端·github
mudtools33 分钟前
在.NET现有系统中快速集成飞书任务分配能力
后端·c#·.net
Wang's Blog34 分钟前
Java 项目实战: 外卖平台优化-从库Slave配置与主从复制验证
java·开发语言
知守观34 分钟前
ThreadLocal + 异步线程导致用户数据串号:一次跨请求数据泄漏的完整复盘
后端
前端冒菜师36 分钟前
我为什么做了 Iris,又为什么停下了它
后端·ai编程