2014-03-14 242 views
4

我有一個連接表的查詢。這是select語句:爲什麼我的MySQL加入緩慢?

SELECT *, A.id AS id, 
     A.username AS username, 
     G.desc AS customer_desc, 
     H.id AS counter, 
     SUM(F.amount_paid) 
FROM tblcheckin AS A 
LEFT OUTER JOIN tblrate AS B ON B.id = A.rate_id 
LEFT OUTER JOIN tblrefaccom_type AS C ON C.id = A.id 
LEFT OUTER JOIN tblcust_bill AS D ON D.check_in_id = A.id 
LEFT OUTER JOIN tblroom AS E ON E.room_no = A.room_id 
LEFT OUTER JOIN tblpayment AS F ON F.check_in_id = A.id 
LEFT OUTER JOIN tblrefcust_type AS G ON G.id = A.customer_desc 
LEFT OUTER JOIN tblindex AS H ON A.id = H.check_in_id 
WHERE A.check_out = "0000-00-00 00:00:00" 
GROUP BY F.check_in_id 
ORDER BY check_out, check_in 

結果:Showing rows 0 - 11 (12 total, Query took 7.4061 sec)

這是Explain SQL

enter image description here

這是我的就是我所做的迄今: 我設置optimizer_search_depth = 0因爲我想它會像這裏提到的那樣工作Joining many tables in mySQL

我在這裏做錯了什麼?我感謝每一個反饋。謝謝。

UPDATE。問題解決了。我在tblpayment,tblcust_bill和tblindex的check_in_id列中添加了索引。這裏是新Explain SQL

enter image description here

+0

您正在對'GROUP BY'使用惡意的MySQL擴展。讀這個。 http://dev.mysql.com/doc/refman/5。5/en/group-by-extensions.html –

+0

感謝您的反饋。我已閱讀文章並將F.check_in_id添加到選擇列表中。但是,它仍然很慢。 – DVA

回答

3

看你的解釋,我可以看到幾個的連接需要全表掃描。您可能沒有A.check_outD.check_in_idF.check_in_id(這是一個基於相對行數的殺手)和H.check_in_id的索引。這意味着它必須掃描整個表格A,D,F和H才能找到相關的行。

索引這4行,查詢次數應該會飛漲。

那個已經說了,我很驚訝這已經不快了,甚至沒有優化。我在每個表格中看到幾萬行 - 除非這些行真的很大(順便說一下,壞的做法 - 將文本/ blob和大列分成不同的表格),您應該能夠得到這些結果少於7秒。更像我期望的70毫秒。我懷疑你必須調整你的MySQL服務器設置 - 使用更多的內存,增加緩衝區大小等,但這些索引應該有很大的幫助。

+0

我認爲這是一個偉大的想法,但@OllieJones關於如何連接下面甚至沒有使用過的表格很有用。看看這個答案吧! –

+0

感謝您的反饋。肯定會試圖修復指數。之後我會發布更新。 – DVA

+0

讓我們知道如果你不知道如何添加索引,我相信我們可以幫助你。基本上ALTER TABLE表ADD KEY(列)是你想要做的。 –

2

您似乎要連接很多不需要的表來滿足您的查詢。這是否會工作,省去了額外的表格?

SELECT A.id AS id, 
     A.username AS username, 
     G.desc AS customer_desc, 
     H.id AS counter, 
     SUM(F.amount_paid) 
FROM tblcheckin AS A 
LEFT OUTER JOIN tblpayment AS F ON F.check_in_id = A.id 
LEFT OUTER JOIN tblrefcust_type AS G ON G.id = A.customer_desc 
LEFT OUTER JOIN tblindex AS H ON A.id = H.check_in_id 
WHERE A.check_out = "0000-00-00 00:00:00" 
GROUP BY F.check_in_id 
ORDER BY check_out, check_in 

您正在使用令人討厭的MySQL hackstension來進行GROUP BY。代之以做。

GROUP BY A.id, A.username, G.desc, H.id 

tblcheckin一個表有多行嗎?如果是這樣,請確保check_out上有一個索引,並將其聲明爲NOT NULL

確保您有在ON條款中提到的列的索引在你JOIN指令,即:

tblpayment.check_in_id 
    tblrefcust_type.id (maybe already a primary key) 
    tblindex.check_in_id 

考慮將覆蓋索引(多列索引)在你的表。這樣,您的查詢所需的數據就可以完全從索引中完全滿足,這將節省查詢查詢磁盤驅動器的時間。儘管如此,很多索引可能會降低插入和更新的速度。

tblcheckin (cneck_out, id, customer_desc, username) 
    tblpayment (check_in_id, amount_paid) 
    tblrefcust_type (id, desc) 
    tblindex  (check_in_id, id) 
+0

你知道這是一個很好的觀點,B,C,D,E表不似乎很重要! –

+0

對這個問題感到抱歉。我忘記在選擇中包含「*」。我複製了今天早上我測試過的查詢。我將編輯該問題。我再次道歉。 – DVA