2013-07-13 61 views
0

表A有500,000個記錄:這個子選擇是在where子句之前還是之後執行的?

id, text, created, b_id 

表B有20'000記錄:

id, text 

A.b_id is FK to b.id 

所以,當我做到以下幾點:

SELECT text, created, (SELECT b.text FROM b WHERE b.id = A.b_id) FROM a WHERE created < now() 

或也

SELECT text, created, (SELECT b.text FROM b WHERE b.id = A.b_id) FROM a LIMIT 0,10 

這個子選擇將在 WHERE子句後執行,所以實際上只能在記錄where created < now()where created < now()之間執行。僅在前十條記錄上或將在的每條記錄上執行排除發生?

謝謝!

+1

您在查詢中缺少'from'子句。 – Guffa

+0

true :)僅僅是一個例子,因爲我的查詢將超過SO存儲功能;)將通過 –

+0

來添加它。還要注意,如果子查詢返回多個結果,則這些查詢將失敗。 – eggyal

回答

2

你應該瞭解SQL連接—例如:

SELECT a.text, a.created, b.text 
FROM a JOIN b ON b.id = a.b_id 
WHERE a.created < NOW() 
LIMIT 0, 10 

然而,爲您解答相關子查詢的問題:

請問子查詢的WHERE子句後執行,所以實際上僅在現在創建<()的記錄上執行。僅在前十條記錄上,或者在排除發生之前在每條記錄上執行?

只有在應用了過濾器/限制後,子查詢纔會被父查詢返回的那些記錄評估。

+0

我非常瞭解SQL連接,我的問題是關於性能,而不是寫其他方式來編寫我的代碼。所以,如果你可以提供一個關於你的代碼在性能上的答案/當聯接將被執行時,這將是有益的,否則... –

+0

@RaphaelJeger:看到我的更新。 – eggyal

+0

謝謝,所以我刪除了我的downvote。這同樣適用於JOIN嗎? –

0

子查詢不會自行執行。整個查詢將由查詢規劃器轉換爲更類似於具有外部聯接的查詢的東西。

因此,不會爲其他表中的每個記錄或每個中間結果記錄執行子查詢。它將被執行一次,並結合主查詢。

查詢計劃的確切結果取決於您在表上具有哪些索引以及表的統計信息告訴查詢計劃者。

+0

似乎並非如此。請參閱[sqlfiddle](http://sqlfiddle.com/#!2/4ed9d/1)。事實上,如果相關子查詢由查詢規劃器轉換爲連接,那麼在性能上不會出現如此巨大的差異,或者需要關於[將子查詢重寫爲連接]手動章節(http://dev.mysql.com /doc/en/rewriting-subqueries.html)? – eggyal

+0

@eggyal:通過更改查詢來測量它,您可以更改結果。您強制查詢計劃程序重複子查詢。 – Guffa

+0

它生成相同的執行計劃...請參閱[sqlfiddle](http://sqlfiddle.com/#!2/4ed9d/2)。 – eggyal

相關問題