2013-06-30 77 views
3

我看到了這種從多個表中選擇多個表的方式,而且我已經實現了這個多年。我想知道的是,如果有什麼方法可以讓它更快。 查詢的背景:我從留言表b/w學生和導師中選擇學生髮布在作業表中的作業中的留言。 導師信息存儲在tutorinfo表中,studentinfo存儲在studentinfo表中。在mysql中加入4個或更多表的查詢速度更快

也請說出這是什麼樣的加入。有人告訴我這是一個交叉連接,但我不確定。直到最近我才知道加入,但從來沒有。這種格式現在已經有相當長的一段時間了。我不確定如何使用連接格式可以使它更好,如果有更好的。

下面是本查詢::

SELECT 
messages.* , 
tutorinfo.id as tutor_id, 
jobs.student_id as student_id, jobs.job_title 
from messages, tutorinfo, studentinfo, jobs where 
messages.job_id= jobs.id and jobs.student_id = '3' and messages.thread_id = '2' and  messages.tutor_id = tutorinfo.id and messages.job_id = jobs.id and studentinfo.id=jobs.student_id 
+0

[不要忘了**採取SO遊**它會引導你如何最好的使用SO](http://stackoverflow.com/about) – Prix

+0

試圖養成使用顯式JOIN語法的習慣。它對你,我們和(在某些情況下)MySQL也更具可讀性。而且,正如其他人指出的那樣,不要包含與結果集無關的表格。 – Strawberry

回答

1

這是你寫在一個更現代的風格選擇語句。在這種風格中,你可以看到連接(注意它們都是內部連接)。你可以告訴它們是內部連接(在我們的兩個查詢中),因爲連接的列是相等的。在你的方法有一個交叉連接或外部連接,你需要特殊的格式(而不是一個=),使用「連接」格式,你使用特殊的語法。

SELECT m.*, 
     t.id as tutor_id, 
     j.student_id as student_id, j.job_title 
from messages m 
join jobs j on m.job_id = j.job_id 
join studentinfo s on j.student_id = s.id 
join tutorinfo t on m.tutor_id = t.id 
where j.student_id = '3' and m.thread_id = '2' 

有一點很清楚 - studentinfo沒有使用,你可以把它拿出來。 除此之外,並將索引添加到所有用作連接的列中,我沒有看到太多的優化方式。

SELECT m.*, 
     t.id as tutor_id, 
     j.student_id as student_id, j.job_title 
from messages m 
join jobs j on m.job_id = j.job_id 
join tutorinfo t on m.tutor_id = t.id 
where j.student_id = '3' and m.thread_id = '2' 
1

使用MySQL JOINS

enter image description here

SELECT 
    jobs.`id` AS jobs_id, 
    jobs.`job_title` AS jobs_job_title, 
    messages.`id` AS messages_id, 
    messages.`job_id` AS messages_job_id, 
    messages.`thread_id` AS messages_thread_id, 
    messages.`tutor_id` AS messages_tutor_id, 
    messages.`student_id` AS messages_student_id, 
    tutorinfo.`id` AS tutorinfo_id 
FROM 
    `messages` messages INNER JOIN `tutorinfo` tutorinfo ON messages.`tutor_id` = tutorinfo.`id` 
    INNER JOIN `jobs` jobs ON messages.`job_id` = jobs.`id` WHERE jobs.student_id = '3' AND messages.thread_id = '2' 

而且看看這些東西

A Visual Explanation of SQL Joins

Visual-Representation-of-SQL-Joins

+0

你爲什麼加入studentinfo?它從未被使用過。 – Hogan

+0

對不起@Hogan,因爲user1849091已經提到了關於studentinfo表....所以我也加入了......看到我的更新..... –

0

這將是一個補充@ Hogan的答案的評論,但我分開發布。在Mysql JOIN中,INNER JOINCROSS JOIN都是合成的等價物。 ,INNER JOIN在沒有連接條件時在語義上是等效的,但,具有較低的優先級。

在原始查詢中,連接條件已放置在where子句中。 Mysql查詢優化器可能會爲當前查詢提供優化的查詢計劃,並通過按優化順序使用INNER JOINS來避免交叉連接和對產品進行篩選。但是,通過略微重新說明,可以明確加入連接條件,強制讀取順序並減少查詢優化程序需要執行的工作。也許這是可以忽略的性能好處。你必須配置才能看到。

SELECT m.*, 
     t.id as tutor_id, 
     j.student_id as student_id, j.job_title 
from messages m 
STRAIGHT_JOIN jobs j on m.job_id = j.job_id and j.student_id = '3' 
STRAIGHT_JOIN tutorinfo t on m.tutor_id = t.id 
where m.thread_id = '2' 

STRAIGHT_JOIN類似於JOIN但左邊的表,右邊前閱讀。來自Mysql documentation

連接優化程序計算連接的表應該是 的順序。該表中讀取順序由LEFT JOIN強行或STRAIGHT_JOIN 幫助聯接優化做的工作更迅速,因爲有 較少表排列檢查

相關問題