JOIN允许按特定条件将多个表在一个SELECT查询中连接,通常通过关键字ON。子查询(或嵌套查询)是指放置在另一个查询内部的查询。JOIN在对具有良好索引的大表进行连接时效果更佳,对优化器更透明,通常执行速度更快。子查询在需要计算聚合函数或存在通过JOIN无法实现的条件时更方便(例如,相关查询)。
JOIN示例:
SELECT employees.name, departments.name FROM employees JOIN departments ON employees.dept_id = departments.id;
子查询示例:
SELECT name FROM employees WHERE dept_id IN ( SELECT id FROM departments WHERE location = 'Moscow' );
“是否认为子查询的使用总是比JOIN慢?”
答案: 不,未必!编写良好的子查询往往会被优化器转换为内部JOIN。此外,有时子查询更有效,例如,当外部查询处理的数据量较少时,而子查询返回提前聚合的结果。
示例:
SELECT name, salary FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
这个子查询将只执行一次。
历史
在一个大型项目中,报告使用了嵌套子查询而不是JOIN。当数据量增加时,查询的执行时间从几秒变为几分钟。替换子查询为JOIN后,性能提升了10倍。
历史
在一个项目中,分析师将带有GROUP BY的查询重写为子查询,未注意到在JOIN级别出现了重复。这导致报告中的数据不正确——由于笛卡尔积,金额被高估了。
历史
在外部循环中使用相关子查询(针对每一行)导致随着表的增长性能完全降级。决定通过JOIN并进行聚合处理——查询处理时间从数小时减少到几分钟。