我一直百思不得其解解決此問題在MySQL的5.0.51a現在相當長的一段:在mysql LEFT不使用索引聯接WHERE子句
當使用LEFT JOIN加入一個表,並使用WHERE子句中連接表的列,mySQL無法使用JOIN中連接表的主索引,即使FORCE INDEX(PRIMARY)也失敗。
- 如果未連接的表的列在WHERE子句中,則一切正常。
- 如果刪除GROUP BY,則也使用該索引。
但我需要他們兩個。
故障: (的EXEC時間在我的特殊情況下可達1000秒)
SELECT *
FROM tbl_contract co
LEFT JOIN tbl_customer cu ON cu.customer_id = co.customer_id
WHERE cu.marketing_allowed = 1 AND co.marketing_allowed = 1
GROUP BY cu.id
ORDER BY cu.name ASC
工作,但沒有解決我的問題:
SELECT *
FROM tbl_contract co
LEFT JOIN tbl_customer cu ON cu.customer_id = co.customer_id
GROUP BY co.id
表結構(轉錄,作爲真正的表更復雜)
tbl_contract:
id: INT(11) PRIMARY
customer_id: INT(11)
marketing_allowed: TINYINT(1)
tbl_customer:
customer_id: INT(11) PRIMARY
marketing_allowed: TINYINT(1)
mySQL EXPLAIN通知PRIMARY作爲可能的鍵加入時,但不使用它。
已經有一個解決辦法:
SELECT (...)
HAVING cu.marketing_allowed = 1
解決了但我們使用的查詢在其他情況下,我們只能選擇在整個聲明中一列問題,但有需求的marketing_allowed列在SELECT語句中被選中。
我也注意到,在所需的表上運行ANALYZE TABLE將會使mySQL 5.5.8在我的本地系統上做正確的事情,但我不能始終確保ANALYZE已經在語句前運行。無論如何,這個解決方案在我們的生產服務器上不能在mySQL 5.0.51a下運行。 :(
有MySQL中的特殊規則,我沒注意到?爲什麼LEFT JOIN不使用索引,如果列顯示在WHERE子句中?爲什麼我不能強迫他們?提前
THX ,
勒
[編輯]
由於一些答覆,我可以用一個訂單時使用INNER JOIN優化查詢,但遺憾的是,雖然看似精絕,MySQL的仍然拒絕使用索引BY條款,正如我發現的那樣:
SELECT *
FROM tbl_contract co
INNER JOIN tbl_customer cu ON cu.customer_id = co.customer_id AND cu.marketing_allowed = 1
WHERE cu.marketing_allowed = 1
ORDER BY cu.name ASC
如果您離開ORDER BY,mySQL將正確使用索引。 我已經刪除了GROUP BY,因爲它在示例中沒有相關性。
[編輯2]
FORCING索引也沒有幫助。所以,問題是:爲什麼mySQL不使用索引進行連接,因爲在連接和減少WHERE子句的結果集之後執行ORDER BY?這通常不應該影響加入...
你怎麼知道「mySQL無法使用主索引」?你檢查過'EXPLAIN'的輸出嗎?你能把它包括在你的問題中嗎? – eggyal
請分享表格結構。 –
嗨,是的,我大量使用了EXPLAIN,午餐休息後我會修改我的請求;) –