-- 方案一:派生表關聯
SELECT e.* FROM emp e
JOIN (SELECT AVG(sal) avg_sal, deptno FROM emp GROUP BY deptno) d
ON e.deptno = d.deptno
WHERE e.sal > d.avg_sal;
-- 方案二:相關子查詢
SELECT * FROM emp e
WHERE e.sal > (SELECT AVG(sal) FROM emp WHERE deptno = e.deptno);
| 維度 | 方案一(派生表) | 方案二(子查詢) |
|---|---|---|
| 執行計劃 | 物化派生表 → Hash Join | 對外層每行執行子查詢(可能轉為 Semi Join) |
| 平均值計算次數 | 每部門一次 | 理論上每行一次,優化器常轉為每部門一次 |
| 臨時表開銷 | 需創建派生表 | 無顯式臨時表 |
| 索引利用 | 需 deptno 索引支持 Join | 需 deptno 索引支持子查詢 |
無絕對優劣,必須在目標數據庫、數據量、索引環境下實測。
-- MySQL
EXPLAIN FORMAT=JSON SELECT ...;
-- Oracle
EXPLAIN PLAN FOR SELECT ...; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
-- SQL Server
SET STATISTICS IO, TIME ON; SELECT ...;
關注 rows、cost、Actual Time 指標。