2012-12-19 40 views
0

我知道有一千個類似的問題,我讀了很多,但我不知道如何提高以下查詢的性能:如何使用「文件排序」和「使用臨時」來優化MySQL查詢(它需要超過10秒)

SELECT DATE_FORMAT(c.date, "%d/%m/%Y") AS ddmmyy, c.idQualification, q.name, 
SUM(idContactList = "") + COUNT(DISTINCT NULLIF(CONCAT(c.idContactList, c.idActivity), "")) AS numCalls 

FROM callsBreakdown c 
LEFT JOIN qualification q ON q.idQualification = c.idQualification 
LEFT JOIN activityCampaign a ON (a.idActivity = c.idActivity) 
LEFT JOIN qualificationCampaign qc ON (qc.idCampaign = a.idCampaign AND qc.idQualification = c.idQualification) 

WHERE c.date BETWEEN "2011-01-01" AND "2012-10-01" 
GROUP BY c.date, q.name 

如果日期範圍很寬,比如1年或更長,則查詢需要10-12秒才能完成。在解釋這callsBreakdown表(Extra列的其他人「使用索引」,他們是快速):

id select_type table type possible_keys key  key_len ref rows Extra 
1 SIMPLE  c  ALL date   NULL  NULL NULL 379553 Using where; Using temporary; Using filesort 

服務器不使用日期索引,需要臨時表和文件排序。任何想法?謝謝!

編輯:我將別名「date」更改爲「ddmmyy」,結果相同。別名不是問題。

編輯2:如果日期範圍兩個月或更小,MySQL的使用日期索引(鍵),而不是「NULL」鍵

+0

索引不保證被使用。 MySQL有一個基於成本的優化器。如果它認爲使用索引的成本大於不使用它的成本,那麼它將不會使用它。 –

回答

1

當你寫GROUP BY date它使用的別名,也就是輸出一個函數調用的位置:

SELECT DATE_FORMAT(c.date, "%d/%m/%Y") AS date, ... 

,而不是嘗試通過組在原表中的列,它應該允許ORDER BY使用索引:

GROUP BY c.date, q.name 
+0

'date'在哪裏呢?這不是別名嗎? –

+0

別名不是問題,我改變它,結果是一樣的。 – Stokres

+0

@Stokres:可能有不止一個問題。 –

相關問題