相关子查询是指子查询中引用外部查询表字段、必须依附外层上下文逐行执行的子查询,如select name from employees e1 where salary > (select avg(salary) from employees e2 where e2.department = e1.department)。

相关子查询的核心在于“外部查询的每一行都会触发一次子查询的执行”,子查询中引用了外部查询的列,因此无法独立运行,必须依附于外层上下文。
什么是相关子查询
相关子查询是子查询中包含对外部查询(主查询)表字段的引用。例如:
SELECT name FROM employees e1 WHERE salary > (SELECT AVG(salary) FROM employees e2 WHERE e2.department = e1.department);
这里子查询里的 e1.department 来自外部查询别名 e1,每次处理 e1 的某一行时,子查询都要重新执行,并代入该行的 department 值来计算对应部门的平均工资。
集企业自助建站、网络营销、商品推广于一体的系统 功能说明: 1、系统采用Microsoft SQL Server大型数据库支持,查询数据库用的全是存储过程,速度和性能极好。开发环境是vs.net,采用4层结构,具有很好的可维护性和可扩冲性。 2、用户注册和登陆 未注册用户只具备浏览商品、新闻和留言功能;要采购商品,需接受服务协议并填写相关注册信息成为正式用户后方可进行,以尽可能减少和避免无效
相关子查询的执行流程
数据库不是先算完子查询再匹配,而是按行驱动、逐行求值:
- 从外部查询获取第一行数据(如某个员工记录)
- 将该行中被子查询引用的列值(如 department)代入子查询的 WHERE 或 ON 条件中
- 执行该次子查询,返回一个标量值(如 AVG)、单行结果或布尔结果
- 用子查询结果判断当前外部行是否满足 WHERE 条件,决定是否保留在最终结果中
- 重复以上步骤,直到外部查询所有行处理完毕
性能特点与优化提示
由于每行都可能引发一次子查询执行,相关子查询天然存在重复计算风险,尤其在外表数据量大时:
- 若子查询涉及大表扫描或复杂聚合,性能下降明显
- 数据库优化器可能尝试重写为 JOIN(如将 AVG 子查询转为窗口函数或派生表),但并非总能成功
- 可考虑用 GROUP BY + 窗口函数 替代(如 AVG(salary) OVER(PARTITION BY department)),避免逐行调用
- 确保子查询中被关联的列(如 e2.department)上有索引,加速每次子查询的过滤
常见误用与识别技巧
判断是否为相关子查询,只需看子查询内部是否出现了外部查询的表别名或列名:
- 子查询里出现 e1.col、outer_table.id 等跨层引用 → 是相关子查询
- 子查询完全独立,不依赖外部任何字段 → 是不相关子查询(可提前一次性执行)
- EXPLAIN 分析时,常看到 “DEPENDENT SUBQUERY” 类型,即明确标识为相关子查询









