主题
面试速答(先看这里)
**一句话结论:**之所以这么做,一方面是因为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 *,只要表结构发生变化(新增/删除字段),缓存可能会失效,导致频繁的查询执行。但是后来缓存被废弃了,这个也就无所谓了。
还有一个就是可能会导致隐患,比如我们之前就出现过,线上增加了一个新的字段,但是这个字段只在数据库中加了,代码中还不能用,这时候select *就会查到这个字段,就会导致处理异常。当然,这个原因并没那么重要,主要还是上面两个问题。