2013-07-25 41 views
1

我只是在學習MYSQL的過程中,有一些我一直在想的東西。在內部連接之前使用子查詢效率更高?

讓我們這個簡單的場景:一個假想的網站採取網上課程,包括4個表:學生,教師,課程和註冊(每門課程一個條目,一個學生已經註冊)

您可以找到DB生成代碼on github

雖然提供的數據庫很小,但爲了保持與我需要的幫助相關,讓我們假設這是一個足夠大的數據庫,效率將成爲一個真正的問題 - 比如說成千上萬的學生,教師等



至於我與MYSQL明白,如果我們想通過「達爾文」被教過的學生的桌子,一個可能的查詢會是這樣:

方法1

SELECT Students.name FROM Teachers 
INNER JOIN Courses ON Teachers.id = Courses.teacher_id 
INNER JOIN Registrations ON Courses.id = Registrations.course_id 
INNER JOIN Students ON Registrations.student_id = Students.id 
WHERE Teachers.name = "Charles Darwin" 

確實返回我們想要的。

+----------------+ 
| name   | 
+----------------+ 
| John Doe  | 
| Jamie Heineman | 
| Claire Doe  | 
+----------------+ 


所以我的問題是:

與我(非常)有限MYSQL的知識,這在我看來,我們在這裏JOIN -ing元素到教師表,這可能會相當大,而我們最終只能在一位老師之後,我們會在查詢的最後過濾掉。

我的「直覺」說,這將是更有效,首先得到我們所需要的老師單行,然後再加入剩下的東西到是不是:

方法2

SELECT Students.name FROM (SELECT Teachers.id FROM Teachers WHERE Teachers.name = 
"Charles Darwin") as Teacher 
INNER JOIN Courses ON Teacher.id = Courses.teacher_id 
INNER JOIN Registrations ON Courses.id = Registrations.course_id 
INNER JOIN Students ON Registrations.student_id = Students.id 

但是,情況真的如此嗎?假設成千上萬的教師和學生,這比第一個查詢更有效嗎?這可能是因爲MYSQL足夠聰明,能夠以更高效的方式解析方法1查詢。


而且,如果任何人都可以提出一個更高效的查詢,我會聽到它也很感興趣。

注意:我以前讀過使用EXPLAIN來弄清楚查詢的效率如何,但我不明白MYSQL能夠解釋結果。這裏的任何洞察力也將非常感激。

+0

我可以提供一個部分答案:如果兩個查詢確實是等價的,那麼使用RDBMS的全部意義在於您不必擔心這種優化。查詢優化器應該爲你找出這些東西。也就是說,許多優化器需要很多指導,這會導致重寫,看起來很像您提供的。它取決於特定的數據庫(和查詢)。 – mzedeler

回答

1

我的「直覺」說,這將是更有效的先得到 因爲我們需要老師單行,再加入剩餘的 東西到這來代替:

你是在方法1中通過使用謂詞Teachers.name = "Charles Darwin"獲得單行。查詢優化器應該確定在加入其他表之前使用此謂詞限制Teacher集合更有效。

如果你不信任的優化器或者想通過使用SELECT STRAIGHT_JOIN ...STRAIGHT_JOIN代替INNER_JOIN確保MySQL的讀取您指定的順序表,以減輕它,你甚至可以強制表中讀取順序工作在查詢中。

您的第二個查詢會得到相同的答案,但可能效率較低,因爲爲您的教師子查詢創建了臨時表。

EXPLAIN documentation是如何解釋EXPLAIN輸出的一個很好的來源。