1.mysql的explain有什么作用?

EXPLAIN 是 MySQL 提供的一个执行计划分析工具。它能模拟优化器执行 SQL 语句,告诉我们 MySQL 到底会怎么执行这条 SQL,从而帮助我们分析性能瓶颈。

在面试或工作中,我查看 EXPLAIN 结果时,主要关注三个最核心的字段

1. type(访问类型 —— 决定快慢的关键) 这是判断查询性能最重要的指标。它的效率从高到低依次是:

  • system > const(主键/唯一索引精确匹配) > eq_ref > ref(普通索引) > range(范围索引) > index > ALL(全表扫描)。

  • 合格标准:通常我们要求至少达到 range 级别,最好是 ref。如果看到 ALL,说明走了全表扫描,必须优化(除非表非常小)。

2. key(实际使用的索引)

  • 它告诉我们 MySQL 实际 选择了哪个索引。

  • 如果显示 NULL,说明没走索引(或者索引失效了),这时就要检查是不是违背了‘最左匹配原则’,或者字段做了函数运算。

  • 补充:配合 key_len 可以计算出联合索引到底被用到了哪几列。

3. Extra(额外信息 —— 这里的‘坑’最多) 这里能看到很多底层细节,我最关注这几个状态:

  • Using filesort(最差):说明 MySQL 需要在内存或磁盘中进行额外的排序,而不是利用索引顺序。这是必须优化的。

  • Using temporary(很差):说明用到了临时表(常用于 GROUP BYDISTINCT),性能损耗大。

  • Using index(最好):说明触发了覆盖索引(Covering Index),不需要回表,性能非常高。

总结EXPLAIN 就像是 SQL 的 X 光机。我通常用它来定点清除项目中的慢查询,主要目标是:消除 ALL(全表扫描),避免 filesort(文件排序),并尽量实现 Using index(覆盖索引)。

2.怎么查看是否有走索引?

同上

3.怎么查看表的索引?

“在日常开发和排查问题时,我主要使用两种方式来查看索引:

1. 最常用的命令:SHOW INDEX

  • 命令SHOW INDEX FROM 表名; (或者 SHOW KEYS FROM 表名;,效果一样)。

  • 核心关注点(不只是看有没有,还要看细节):

    • Non_unique:如果是 0,说明是唯一索引(或主键);如果是 1,说明是普通索引。

    • Seq_in_index:这对于联合索引非常重要,它显示了字段在索引中的顺序,帮助我判断是否符合‘最左匹配原则’。

    • Cardinality(基数):这是一个估算值,代表索引中不重复值的数量。这个值越高,说明索引区分度越好,查询效率通常越高。如果这个值很低,可能需要考虑优化索引。

2. 最直观的方式:SHOW CREATE TABLE

  • 命令SHOW CREATE TABLE 表名;

  • 场景:这个命令会打印出创建表的完整 DDL 语句。

  • 优点:对于复杂的联合索引或者要查看索引的具体类型(如 USING BTREE),直接看 DDL 往往比看列表更清晰,而且可以直接复制出来用于在测试库复现结构。

3. 批量查询(运维视角):information_schema

  • 如果我需要写脚本统计整个数据库的索引情况,我会查询 information_schema.STATISTICS 表,这样可以进行更复杂的 SQL 筛选。”

4.给你张表,发现查询速度很慢,你有那些解决方案

总结: 优化的优先级是:索引 > SQL 改写 > 缓存 > 分库分表。绝大多数情况下,一个合理的索引就能解决问题。”

“这是一个非常经典的生产环境调优问题。我通常会按照**‘先诊断,后调优,最后动架构’**的思路,分三步走:

第一步:诊断与定位(不盲目瞎猜)

  • 开启慢查询日志 (Slow Query Log):首先抓到是哪条 SQL 慢。

  • 分析执行计划 (EXPLAIN):对慢 SQL 执行 EXPLAIN,重点看 type 是否走了全表扫描(ALL),以及 key 是否用到了预期的索引,Extra 有没有出现 Using filesortUsing temporary

第二步:SQL 与索引优化(低成本,高收益) 这是解决 80% 问题的阶段:

  1. 索引调优

    • 补索引:给 WHEREORDER BYGROUP BYJOIN 的关联字段加上索引。

    • 遵循最左匹配:如果是联合索引,确保查询条件满足最左匹配原则。

    • 覆盖索引:尽量只查询需要的字段(避免 SELECT *),让查询直接在索引树上完成,避免回表。

  2. SQL 改写

    • 避免索引失效:检查有没有在索引列上做计算、函数操作,或者使用了 !=LIKE '%xx'(左模糊)。

    • 优化连表JOIN 查询时,确保小表驱动大表,且被驱动表的连接字段一定要有索引。

    • 优化深分页:针对 LIMIT 1000000, 10 这种深分页,利用子查询 ID标签记录法where id > last_id)来替代。

第三步:架构与表结构优化(高成本,最后手段) 如果 SQL 已经优化到极致,但数据量确实太大(比如单表过亿),才考虑这层:

  1. 引入缓存 (Redis):对于读多写少的热点数据,利用 Redis 抗压。

  2. 冷热分离:将历史归档数据移到冷库,主表只留最近的数据。

  3. 分库分表

    • 垂直拆分:把大字段(如 Text/Blob)拆到另一张附表中。

    • 水平拆分:如果单表超过 2000 万行且性能明显下降,考虑 Sharding(分库分表)。

5.如果Explain用到的索引不正确的话,有什么办法干预吗?

  • FORCE INDEX(强推 - 最常用)

    • 用法SELECT * FROM table FORCE INDEX (idx_a) ...

    • 作用:强制 MySQL 从这个索引和全表扫描中选一个(基本就会选这个索引)。这是最强硬的干预。

  • IGNORE INDEX(屏蔽)

    • 用法SELECT * FROM table IGNORE INDEX (idx_wrong) ...

    • 作用:如果你发现 MySQL 总是傻傻地去走一个效率极低的索引,你可以显式地‘禁用’它,逼优化器去选别的。

  • USE INDEX(建议)

    • 这只是给优化器一个‘建议’,MySQL 还是有可能不听你的。