2011-10-14 163 views
1

我有4個表MYSQL連接查詢優化與多tablesU

類,考試,問題意識,UserResponses

Class -> ID , Name 
Exam -> ID,Name,Class_ID_FK 
Questions -> ID,Question,Exam_ID,FK 
Answers -> ID,Answer,Question_ID_Fk 
UserResponses -> ID,UserID,Answer_ID_fk,Question_ID_fk 

我想獲取所有用戶寄託給定class.I都的所有考試寫了一個查詢,但我想看看別人的建議,如果我正確的方向走,因爲這個查詢的500個實例可能同時在我的系統中運行。

select r.answer_id_fk,r.userid,q.question,a.answer,e.name,e.class_id_fk 
from Exams e 
join Questions q on q.exam_id_fk = e.id 
join Answers a on a.question_id_fk = q.id 
left join UserResponses r on r.answer_id_fk = a.id 
where e.class_id_fk =105585; 

我認爲這最終會經歷數據庫中的所有行,最終可能會崩潰。

解釋顯示了這一點。它返回了35行,這是正確的。我在問題表中有18091行.20423在回答中。並在答案中爲'67108'。

1, SIMPLE, a, ALL, , , , , 67108, 
1, SIMPLE, q, eq_ref, PRIMARY, PRIMARY, 25, db_qa_dev.a.question_id_fk, 1, 
1, SIMPLE, c, eq_ref, PRIMARY, PRIMARY, 25, db_qa_dev.q.category_id_fk, 1, Using where 
1, SIMPLE, r, ref, ANSWERID_INDEX, ANSWERID_INDEX, 26, db_qa_dev.a.id, 15, Using index 
+4

這不是租賃編碼器 - 顯示你已經完成了一些工作。 –

+1

如何發佈您的查詢?然後我們可以提出更多的建議。 – Bojangles

+0

@JamWaffles已發佈查詢。 –

回答

2

解釋計劃出來的方式,它看起來像你的一個外鍵索引缺失。 MySQL引擎應該尋找最佳查詢計劃,這通常意味着從索引上過濾最多的數據開始並從那裏開始工作。我不知道實際數據的外觀如何,但我猜想e.class_id_fk上的限制應該是相當嚴格的,所以引擎可能會先過濾掉這些行。那麼,因爲你的所有參與者都包含簡單的FK/PK關係,所以它只會加入其他表中的單行。

我能想到的唯一原因是爲什麼它可能不這樣做是因爲其中一個表中的數據真的很棘手(例如,Exam中的每一行都具有相同的class_id_fk值),或者您缺少您的FK專欄中的索引。

缺少FK列上的索引可能會使優化程序決定更換不同的路由比每隔JOIN必須掃描該表更快。在大多數情況下,您總是需要在所有FK上使用索引,因爲這些列往往傾向於JOIN,因此索引對於讀取非常有用。

+0

感謝您的詳細解釋。此鏈接可能有助於某人。 http://hackmysql.com/case4 –

1

如果您在表格上強制使用最少匹配的straight_join,則查詢速度應該更快。
請注意,只能使用straight_join替換內部聯接,因爲左側聯接不會減少結果集中的行數。

不是100%確定,因爲您的解釋select與您的查詢不符。

SELECT r.answer_id_fk,r.userid,q.question,a.answer,e.name,e.class_id_fk 
FROM Exams e 
STRAIGHT_JOIN Questions q ON (e.class_id_fk = '105585' AND q.exam_id_fk = e.id) 
STRAIGHT_JOIN Answers a on a.question_id_fk = q.id 
LEFT JOIN UserResponses r on r.answer_id_fk = a.id 
+0

我試過了STRAIGHT_JOIN,並表明它可以優化查詢和其他方式。我使用它後,沒有海峽加入索引,它工作正常,但它只是簡單地忽略了我的索引。 –