Skip to content

面试速答(先看这里)

**一句话结论:**之所以这么做,一方面是因为select * 会返回所有列的数据,而很多情况下,我们只需要其中一部分数据,全部查询会导致 不必要的I/O开销 。

60秒标准回答:

SELECT * 表示查询一张表中的所有的字段,但是一般线上都不允许直接用select *查询的,都是要求大家指明要查询的字段名,如 select a,b,c

之所以这么做,一方面是因为select * 会返回所有列的数据,而很多情况下,我们只需要其中一部分数据,全部查询会导致 不必要的I/O开销 。而且也会增加数据库和应用程序之间的 数据传输的开销 ,而且对象查询过来之后放到内存中,也会 占用更多的空间

而且,有些数据如果直接返回给前端,直接select *,可能也会把一些本来无关的数据给返回回去了,但是有些数据其实是不该返回的。就 可能导致数据泄漏 、

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

回答主线:

  • **要点1:**SELECT * 表示查询一张表中的所有的字段,但是一般线上都不允许直接用select *查询的,都是要求大家指明要查询的字段名,如 select a,b,c 。
  • **要点2:**而且,有些数据如果直接返回给前端,直接select *,可能也会把一些本来无关的数据给返回回去了,但是有些数据其实是不该返回的。
  • **要点3:**其次,数据库通常会使用 覆盖索引 来优化查询,这样可以减少回表,提升性能,但是 SELECT * 可能导致查询 无法使用覆盖索引 ,从而增加 I/O 和查询时间。
  • **要点4:**在以前,数据库还支持缓存的时候,用了 SELECT * ,只要表结构发生变化(新增/删除字段),缓存可能会失效,导致频繁的查询执行。
  • **要点5:**还有一个就是可能会导致隐患,比如我们之前就出现过,线上增加了一个新的字段,但是这个字段只在数据库中加了,代码中还不能用,这时候select *就会查到这个字段,就会导致处理异常。

**记忆锚点:**select → SELECT → 覆盖索引 → 但是后来缓存 → 只要表结构 → 而且对象

关键取舍:

  • 就 可能导致数据泄漏 、 其次,数据库通常会使用 覆盖索引 来优化查询,这样可以减少回表,提升性能,但是 SELECT * 可能导致查询 无法使用覆盖索引 ,从而增加 I/O 和查询时间。

易错提醒:

  • 还有一个就是可能会导致隐患,比如我们之前就出现过,线上增加了一个新的字段,但是这个字段只在数据库中加了,代码中还不能用,这时候select *就会查到这个字段,就会导致处理异常。

加分表达:

  • 而且,有些数据如果直接返回给前端,直接select *,可能也会把一些本来无关的数据给返回回去了,但是有些数据其实是不该返回的。
  • 在以前,数据库还支持缓存的时候,用了 SELECT * ,只要表结构发生变化(新增/删除字段),缓存可能会失效,导致频繁的查询执行。

追问准备:

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

典型回答 ​

SELECT * 表示查询一张表中的所有的字段,但是一般线上都不允许直接用select *查询的,都是要求大家指明要查询的字段名,如select a,b,c 。

之所以这么做,一方面是因为select * 会返回所有列的数据,而很多情况下,我们只需要其中一部分数据,全部查询会导致不必要的I/O开销。而且也会增加数据库和应用程序之间的数据传输的开销,而且对象查询过来之后放到内存中,也会占用更多的空间。

而且,有些数据如果直接返回给前端,直接select *,可能也会把一些本来无关的数据给返回回去了,但是有些数据其实是不该返回的。就可能导致数据泄漏、

其次,数据库通常会使用覆盖索引 来优化查询,这样可以减少回表,提升性能,但是SELECT * 可能导致查询无法使用覆盖索引,从而增加 I/O 和查询时间。

📄 ✅什么是索引覆盖、索引下推?

打开文档:✅什么是索引覆盖、索引下推?

在以前,数据库还支持缓存的时候,用了SELECT *,只要表结构发生变化(新增/删除字段),缓存可能会失效,导致频繁的查询执行。但是后来缓存被废弃了,这个也就无所谓了。

📄 ✅为什么MySQL 8.0要取消查询缓存?

打开文档:✅为什么MySQL 8.0要取消查询缓存?

还有一个就是可能会导致隐患,比如我们之前就出现过,线上增加了一个新的字段,但是这个字段只在数据库中加了,代码中还不能用,这时候select *就会查到这个字段,就会导致处理异常。当然,这个原因并没那么重要,主要还是上面两个问题。