主题
面试速答(先看这里)
**一句话结论:**exist和in都是SQL中用于子查询的,他们主要的区别就是实际执行中的执行逻辑的差别,之所以放在一起比较是因为他们通常可以实现同样的功能。
60秒标准回答:
exist和in都是SQL中用于子查询的,他们主要的区别就是实际执行中的执行逻辑的差别,之所以放在一起比较是因为他们通常可以实现同样的功能
比如说查询所有工作地在北京的员工,如果员工表中并没有具体的地址,而只有部门的id,而部门表中才有地址名称的时候,可以用以下方式实现这个功能
in可以用来判断某个值是否在一个结果集里
**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点
回答主线:
- **要点1:**比如说查询所有工作地在北京的员工,如果员工表中并没有具体的地址,而只有部门的id,而部门表中才有地址名称的时候,可以用以下方式实现这个功能:
- **要点2:**exists用来判断子查询是否返回至少一行数据。
- **要点3:**1、在使用in做子查询的时候,通常不需要关联条件,而使用exists的时候,需要有一个关联条件,如 d.id = e.dept_id
- **要点4:**2、in后面要跟的是一个结果集, in (xxx) ,这里的xxx就要是一个结果集,如id的列表。
- **要点5:**1、如果外部表(例子中的employees表)非常大,建议用IN 。
**记忆锚点:**EXISTS → exists → exist → xxx → edept_id → did
关键取舍:
- 而 IN 只执行一次子查询,其性能瓶颈主要在子查询结果集生成和后续的查找上。
加分表达:
- 比如说查询所有工作地在北京的员工,如果员工表中并没有具体的地址,而只有部门的id,而部门表中才有地址名称的时候,可以用以下方式实现这个功能: in可以用来判断某个值是否在一个结果集里。
- 只要子查询对于当前外部行返回至少一行记录, EXISTS 就立即返回 TRUE ,则认为匹配成功。
- 1、如果外部表(例子中的employees表)非常大,建议用IN 。
追问准备:
- 围绕「EXISTS」:底层原理是什么?使用时有哪些边界和常见坑?
- 围绕「exists」:底层原理是什么?使用时有哪些边界和常见坑?
- 围绕「exist」:底层原理是什么?使用时有哪些边界和常见坑?
- 如果线上出现异常,你会如何定位、验证并规避?
典型回答
exist和in都是SQL中用于子查询的,他们主要的区别就是实际执行中的执行逻辑的差别,之所以放在一起比较是因为他们通常可以实现同样的功能。
比如说查询所有工作地在北京的员工,如果员工表中并没有具体的地址,而只有部门的id,而部门表中才有地址名称的时候,可以用以下方式实现这个功能:
bash
SELECT *
FROM employees e
WHERE e.dept_id IN (
SELECT d.id FROM departments d WHERE d.location = 'Beijing'
);in可以用来判断某个值是否在一个结果集里。
和
bash
SELECT *
FROM employees e
WHERE EXISTS (
SELECT 1 FROM departments d WHERE d.location = 'Beijing' AND d.id = e.dept_id
);exists用来判断子查询是否返回至少一行数据。
他们之间有以下几个区别:
1、在使用in做子查询的时候,通常不需要关联条件,而使用exists的时候,需要有一个关联条件,如d.id = e.dept_id
- in之所以不需要关联条件,是因为在in的过程中其实就是在做关联条件的判断了,即用e.dept_id和子查询中返回的d.id的结果集做值匹配。
2、in后面要跟的是一个结果集,in (xxx),这里的xxx就要是一个结果集,如id的列表。而exists后面要跟的是一个布尔值(true or false),exist (xxx),这里的xxx就是一个布尔判断,true 或者 false。
3、in和exist的执行逻辑是不一样的
- in的执行逻辑是,它先执行内部子查询,得到一个结果集。然后,它对外部查询中的每一行,检查该行的指定列值是否存在于这个结果集中。
- exist的执行逻辑是,它对外部查询中的每一行,都通过关联条件(
**d.id = e.dept_id**)执行一次关联子查询。只要子查询对于当前外部行返回至少一行记录,**EXISTS**就立即返回**TRUE**,则认为匹配成功。
那么如何选择呢?
1、如果外部表(例子中的employees表)非常大,建议用IN。因为EXISTS 需要为外部表的每一行执行一次子查询。如果子查询本身不高效(比如缺少索引),这会非常慢。而IN 只执行一次子查询,其性能瓶颈主要在子查询结果集生成和后续的查找上。
2、如果子查询返回的结果(例子中的departments在北京的查询结果)比较大,那么建议用EXISTS,因为IN的话会有部分结果集生成的成本。