不,選擇列表中的相關子查詢沒有被MySQL優化。
您可以通過使用EXPLAIN來確認此優化計劃的報告。下面是一個使用測試數據庫的類似查詢:
mysql> explain select *, (SELECT COUNT(*) FROM cast_info where cast_info.role_id = role_type.id) AS c
from role_type\G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: role_type
partitions: NULL
type: index
possible_keys: NULL
key: role
key_len: 98
ref: NULL
rows: 12
filtered: 100.00
Extra: Using index
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: cast_info
partitions: NULL
type: ref
possible_keys: cr
key: cr
key_len: 4
ref: imdb.role_type.id
rows: 2534411
filtered: 100.00
Extra: Using index
選擇類型依賴SUBQUERY意味着子查詢會爲外層查詢的每一行被執行多次,大概一次。
比較與解釋的手動優化查詢:
mysql> explain select r.*, COUNT(c.id) AS c from role_type AS r left outer join cast_info as c on r.id = c.role_id group by r.id\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: r
partitions: NULL
type: index
possible_keys: PRIMARY,role
key: PRIMARY
key_len: 4
ref: NULL
rows: 12
filtered: 100.00
Extra: NULL
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: c
partitions: NULL
type: ref
possible_keys: cr
key: cr
key_len: 4
ref: imdb.r.id
rows: 2534411
filtered: 100.00
Extra: Using index
這表明接入第二表只是一個簡單的通過引用加入。
您也可以使用MySQL query profiler進行測試。這裏的第二個查詢,使用聯接:
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000167 |
| checking permissions | 0.000015 |
| checking permissions | 0.000016 |
| Opening tables | 0.000050 |
| init | 0.000059 |
| System lock | 0.000044 |
| optimizing | 0.000011 |
| statistics | 0.000151 |
| preparing | 0.000099 |
| Sorting result | 0.000019 |
| executing | 0.000010 |
| Sending data | 9.700879 |
| end | 0.000024 |
| query end | 0.000022 |
| closing tables | 0.000017 |
| freeing items | 0.000243 |
| cleaning up | 0.000056 |
+----------------------+----------+
而這裏的一個與相關子查詢:
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000152 |
| checking permissions | 0.000014 |
| checking permissions | 0.000013 |
| Opening tables | 0.000050 |
| init | 0.000067 |
| System lock | 0.000042 |
| optimizing | 0.000010 |
| statistics | 0.000367 |
| preparing | 0.000033 |
| optimizing | 0.000015 |
| statistics | 0.000032 |
| preparing | 0.000020 |
| executing | 0.000010 |
| Sending data | 0.000191 |
| executing | 0.000010 |
| Sending data | 4.103899 |
| executing | 0.000018 |
| Sending data | 2.413570 |
| executing | 0.000018 |
| Sending data | 0.043924 |
| executing | 0.000022 |
| Sending data | 0.037834 |
| executing | 0.000020 |
| Sending data | 0.014127 |
| executing | 0.000021 |
| Sending data | 0.089977 |
| executing | 0.000023 |
| Sending data | 0.045968 |
| executing | 0.000024 |
| Sending data | 0.000044 |
| executing | 0.000005 |
| Sending data | 0.190935 |
| executing | 0.000034 |
| Sending data | 1.046394 |
| executing | 0.000018 |
| Sending data | 0.017567 |
| executing | 0.000021 |
| Sending data | 0.882959 |
| end | 0.000046 |
| query end | 0.000023 |
| closing tables | 0.000018 |
| freeing items | 0.000248 |
| cleaning up | 0.000025 |
+----------------------+----------+
你可以看到,子查詢導致多次執行。就我而言,我在role_type表中只有幾行,但如果您有數百或數千個,則子查詢執行的次數可能會變得很長,以至於事件探查器會截斷該報告。
我不明白引用的問題是如何重複的,因爲它涉及'in'運算符。 – 2014-09-02 02:36:35
。 。如果你想知道MySQL如何處理查詢,請了解'explain'。您擁有的兩個查詢將具有不同的執行路徑。 – 2014-09-02 02:37:23
謝謝:D我會今天檢查 – 2014-09-02 13:18:12