Skip to content

面试速答(先看这里)

**一句话结论:**如何通过SQL 审查发现SQL存在性能问题?

60秒标准回答:

如何通过SQL 审查发现SQL存在性能问题?其实这个问题就是考察你知道不知道都有哪些情况可能到导致一个SQL执行的慢,我们在下面的文章中介绍了可能会导致一个SQL执行慢的原因

可以通过SQL审查发现的问题有以下几个

2、多表join

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**可以通过SQL审查发现的问题有以下几个:
  • **要点2:**首先,代码审查的时候,我们也可以直接把SQL拿到,去数据库中执行一把Explain,看看索引的情况,是不是符合预期的。
  • **要点3:**这个最容易了,肉眼看一下,算一下就行了,一次查询的字段尽量不要超过20个,并且尽量使用索引覆盖查询、尽量避免无脑使用 SELECT * 查询
  • **要点4:**区分度指索引列中不重复值的数量与总行数的比值。
  • **要点5:**但是需要注意,并不是所引起区分度不高就不能用,有些特殊情况还是可以用的:

**记忆锚点:**SQL → WHERE → order → JOIN → Transactional → create_time

关键取舍:

  • 如何通过SQL 审查发现SQL存在性能问题?
  • 如果区分度极低(例如在性别字段 gender 或状态字段 status 上建索引),数据库优化器在计算成本后,会认为走索引再回表的代价比直接全表扫描还要高,从而主动放弃索引。

易错提醒:

  • 这个最容易了,肉眼看一下,算一下就行了,一次查询的字段尽量不要超过20个,并且尽量使用索引覆盖查询、尽量避免无脑使用 SELECT * 查询 区分度指索引列中不重复值的数量与总行数的比值。
  • 但是需要注意,并不是所引起区分度不高就不能用,有些特殊情况还是可以用的: 长事务会长时间持有锁或者占用数据库连接。

加分表达:

  • 检查SQL中是否存在order by这样的操作,以及order by的字段是否有索引 查询是否遵循最左前缀匹配 检查 JOIN 的表数量,通常建议单次 JOIN 不超过 3 张表。
  • 其实这个问题就是考察你知道不知道都有哪些情况可能到导致一个SQL执行的慢,我们在下面的文章中介绍了可能会导致一个SQL执行慢的原因: 可以通过SQL审查发现的问题有以下几个: 2、多表join 3、查询字段太多 4、表中数据量太大 5、索引区分度不高 6、数据库连接数不够 7、数据库的表结构不合理 8、数据库IO或者CPU比较高 9、数据库参数不合理 10…

追问准备:

  • 围绕「SQL」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「WHERE」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「order」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

典型回答 ​

如何通过SQL 审查发现SQL存在性能问题?其实这个问题就是考察你知道不知道都有哪些情况可能到导致一个SQL执行的慢,我们在下面的文章中介绍了可能会导致一个SQL执行慢的原因:

📄 ✅如何进行SQL调优?

打开文档:✅如何进行SQL调优?

可以通过SQL审查发现的问题有以下几个:

1、索引失效

2、多表join

3、查询字段太多

4、表中数据量太大

5、索引区分度不高

6、数据库连接数不够

7、数据库的表结构不合理

8、数据库IO或者CPU比较高

9、数据库参数不合理

10、事务比较长

11、锁竞争导致的等待

12、深分页问题

被我标红的是我们可以通过代码审查发现的问题。其他的几个问题不太好通过代码审查发现。一个一个说。

索引失效 ​

首先,代码审查的时候,我们也可以直接把SQL拿到,去数据库中执行一把Explain,看看索引的情况,是不是符合预期的。走没走索引、走了哪个索引这些都可以看的。

📄 ✅SQL执行计划分析的时候,要关注哪些信息?

打开文档:✅SQL执行计划分析的时候,要关注哪些信息?

我们在下面的文章中介绍了常见的索引失效的情况:

📄 ✅索引失效的问题是如何排查的,有哪些种情况?

打开文档:✅索引失效的问题是如何排查的,有哪些种情况?

重点关注

  • WHERE 子句中是否对字段使用了函数(如 YEAR(create_time) = 2023)。
  • 检查是否存在隐式类型转换(如 varchar 类型的字段传入了数字 WHERE phone = 13800138000)。
  • 检查是否使用了左模糊查询(LIKE '%keyword')。
  • 检查是否出现索引列参与了计算(age +1 = 12)
  • 检查sql中是否出现or、not null、!=、in等操作。
  • 检查SQL中是否存在order by这样的操作,以及order by的字段是否有索引
  • 查询是否遵循最左前缀匹配

多表join ​

📄 ✅为什么大厂不建议使用多表join?

打开文档:✅为什么大厂不建议使用多表join?

  • 检查 JOIN 的表数量,通常建议单次 JOIN 不超过 3 张表。
  • 检查关联字段(ON 条件)是否都有索引,且数据类型、字符集完全一致。
  • 检查是否用小表作为驱动表去驱动大表(小表驱动大表原则)。

📄 ✅MySQL 为什么是小表驱动大表,为什么能提高查询性能?

打开文档:✅MySQL 为什么是小表驱动大表,为什么能提高查询性能?

查询字段太多 ​

这个最容易了,肉眼看一下,算一下就行了,一次查询的字段尽量不要超过20个,并且尽量使用索引覆盖查询、尽量避免无脑使用 SELECT *查询

索引区分度不高 ​

区分度指索引列中不重复值的数量与总行数的比值。如果区分度极低(例如在性别字段 gender 或状态字段 status 上建索引),数据库优化器在计算成本后,会认为走索引再回表的代价比直接全表扫描还要高,从而主动放弃索引。

  • 审查单列索引是否建在了枚举值极少(如男/女、是/否)的字段上。
  • 审查联合索引的列顺序,是否把区分度低的字段放在了最前面(违反了最左前缀原则的有效利用)。

但是需要注意,并不是所引起区分度不高就不能用,有些特殊情况还是可以用的:

📄 ✅区分度不高的字段建索引一定没用吗?

打开文档:✅区分度不高的字段建索引一定没用吗?

事务比较长 ​

长事务会长时间持有锁或者占用数据库连接。同时,长事务会导致 Undo Log 无法及时清理,增加存储引擎(如 InnoDB)的 MVCC 版本链遍历开销,甚至引发主从延迟。

📄 ✅代码中使用长事务,会带来哪些问题?

打开文档:✅代码中使用长事务,会带来哪些问题?

长事务通过代码也能发现的,这个就不是看SQL,而是看具体的service的方法

  • 检查事务块(@Transactional )内部是否包含了非数据库操作,如 RPC 调用、HTTP 请求、复杂的内存计算或文件读写。
  • 检查是否存在循环内执行 SQL 或等待用户输入的情况。

深分页问题 ​

📄 ✅MySQL的深度分页如何优化

打开文档:✅MySQL的深度分页如何优化

对于有一些定时任务比较常出现这个问题,一定要提前关注,有没有可能存在要翻很多页的情况。

  • 检查分页 SQL 中 LIMIT 的偏移量(Offset)是否可能随着业务增长而变得极大。
  • 检查是否允许用户直接跳转到百万级之后的页码。