兩者的各種叫法
- 相關子查詢叫做:
Correlated Subqueries
- 非相關子查詢也叫普通子查詢或嵌套子查詢:
Nested SubQueries
相關子查詢MySQL解釋
相關子查詢是一個子查詢中引用了某張表且這張表也在子查詢外部被使用到。比如:
SELECT * FROM t1
WHERE column1 IN (
SELECT column1 FROM t2
WHERE t2.column2 = t1.column2);
請注意子查詢有一個t1表column2的引用,盡管子查詢的from語句中沒有涉及t1表,這時mysql執行子查詢卻發現t1表在外部查詢中。
假設表t1有一行數據(column1=5,column2=6),與此同時表t2有一行數據(column1=5,column2=7)。
如果是簡單的子查詢:
... WHERE column1 = ANY (SELECT column1 FROM t2)
結果將會是true,有數據返回。但是在這個例子中,where子句中的子查詢會返回false,查不到任何數據,因為兩張表的column2不匹配。
相關子查詢
和普通子查詢
(也叫非相關子查詢
)的差別就在於這子查詢中是否有對外部查詢中涉及到的表的引用。
規則范圍: MySQL從內到外執行執行。比如:
SELECT column1 FROM t1 AS x
WHERE x.column1 = (SELECT column1 FROM t2 AS x
WHERE x.column1 = (SELECT column1 FROM t3
WHERE x.column2 = t3.column1));
在這條語句中,x.column2
一定是表t2的列,因為查詢SELECT column1 FROM t2 AS x ...
別名是x,它不是表t1的列是因為SELECT column1 FROM t1 ...
是一個外部查詢。它倆中間還隔着一對圓括號。
相關子查詢Wikipedia解釋
相關子查詢是使用外部查詢中的值的子查詢(嵌套在另一個查詢中的查詢)。因為子查詢需為外部查詢返回的每一行執行一次,所以它可能會很慢。
SELECT employee_number, name
FROM employees emp
WHERE salary > (
SELECT AVG(salary)
FROM employees
WHERE department = emp.department);
在上面的查詢中,外部查詢為:
SELECT employee_number, name
FROM employees emp
WHERE salary > ...
內部查詢(相關子查詢)為:
SELECT AVG(salary)
FROM employees
WHERE department = emp.department
在上面的嵌套查詢中,須為每個員工重新執行內部查詢。
相關子查詢執行步驟拆解
看完官方和Wiki的解釋,對相關子查詢的描述基本一樣,用自己的話說就是:
相關子查詢被用來做逐行的處理,子查詢會為外部查詢出來的每一行執行內部SQL。(外部語句也可為update或delete語句)
可拆分成下面三個步驟:
- 外部查詢拿到所有行
- 內部查詢使用外部查詢出來的每一行來執行自己邏輯
- 內部查詢有結果返回則當前外部行被保留最終返回否則繼續執行下一行
相關子查詢和嵌套查詢的區別
- 執行順序:相關子查詢是由外部查詢驅動內部查詢。 而正常的嵌套查詢中,內部查詢首先被立即執行,返回的值被外部查詢使用並執行外部查詢。
- 依賴性:相關子查詢內部查詢依賴於外部查詢進行處理,而在嵌套查詢中外部查詢依賴於內部查詢。
- 性能:使用相關子查詢會使性能降低,因為它執行的次數遠遠大於嵌套查詢的次數