2013-03-07 91 views
0

我有一個SQL查詢超過3.5秒來返回計數。查看查詢的蹤跡,它看起來像所有的索引正在使用。我能做些什麼來優化這個合理的執行?使用多個連接優化MySQL計數查詢

我在此先感謝。


Link to trace

SQL細節

查詢

SELECT count(DISTINCT `workorders`.id) AS count_all FROM `workorders` 
LEFT OUTER JOIN `users` ON `users`.id = `workorders`.user_id 
LEFT OUTER JOIN `assets` ON `assets`.id = `workorders`.asset_id 
LEFT OUTER JOIN `users` completed_by_users_workorders ON `completed_by_users_workorders`.id = `workorders`.completed_by_user_id 
LEFT OUTER JOIN `messages` ON messages.workorder_id = workorders.id LEFT OUTER JOIN `priorities` ON `priorities`.id = `workorders`.priority_id 
LEFT OUTER JOIN `suspension_reasons` ON `suspension_reasons`.id = `workorders`.suspension_reason_id 
LEFT OUTER JOIN `job_types` ON `job_types`.id = `workorders`.job_type_id 
LEFT OUTER JOIN `workorder_statuses` ON `workorder_statuses`.id = `workorders`.workorder_status_id 
LEFT OUTER JOIN `workorder_types` ON `workorder_types`.id = `workorders`.workorder_type_id 
LEFT OUTER JOIN `workorder_tasks` ON workorder_tasks.workorder_id = workorders.id 
LEFT OUTER JOIN `frequencies` ON `frequencies`.id = `workorder_tasks`.frequency_id 
LEFT OUTER JOIN `facilities` ON `facilities`.id = `workorders`.facility_id 
LEFT OUTER JOIN `locations` ON `locations`.id = `workorders`.location_id 
WHERE ((((workorders.workorder_status_id = ?)) AND (workorders.application = ?)) AND (workorders.facility_id = ?)) 

時間3791毫秒 查詢分析(顯示詳細信息)

跟蹤 * 工作訂單 *
該表是與此索引檢索:facility_id,app_fac,workorder_status_id 您可以通過查詢僅內場加快此查詢該指數。或者,您可以創建包含查詢中每個字段(包括主鍵)的索引。

掃描了該表的大約33850行。

用戶
該表是與該索引檢索:PRIMARY 大約1行該表的被掃描。

資產
該表是與該索引檢索到:PRIMARY

大約1行該表的被掃描。

completed_by_users_workorders
該表是與該索引檢索到:PRIMARY

大約1行該表的被掃描。

消息
該表是與該索引檢索到:workorder_id

約2行該表的進行掃描。

優先
該表是與該索引檢索到:PRIMARY

大約1行該表的被掃描。

suspension_reasons
該表是與該索引檢索到:PRIMARY

大約1行該表的被掃描。

job_types
該表是與該索引檢索到:PRIMARY

大約1行該表的被掃描。

workorder_statuses
該表是與該索引檢索到:PRIMARY

大約1行該表的被掃描。

workorder_types 該表是與該索引檢索到:PRIMARY

大約1行該表的被掃描。

workorder_tasks 該表是與此索引檢索:index_workorder_tasks_on_workorder_id 您可以加快通過查詢僅僅是索引內的字段此查詢。或者,您可以創建包含查詢中每個字段(包括主鍵)的索引。

掃描了該表的大約1行。

頻率 該表是與該索引檢索到:PRIMARY

大約1行該表的被掃描。

設施
該表是與該索引檢索到:PRIMARY

大約1行該表的被掃描。

位置
該表是與該索引檢索到:PRIMARY

大約1行該表的被掃描。

+0

它可能有助於顯示創建此查詢的模型。 – 2013-03-07 17:30:18

回答

2

除非我失去了一些東西,你有一堆LEFT JOIN S的不影響最終結果(您選擇distinct workorders.id - 我想這是一個PK列然後只在重要的是,WHERE ((((workorders.workorder_status_id = ?)) AND (workorders.application = ?)) AND (workorders.facility_id = ?)所以我相信你能。擺脫所有LEFT JOIN S和1臺進行優化更容易的生活寫只需選擇....

SELECT count(*) AS count_all 
FROM `workorders` 
WHERE ((((workorders.workorder_status_id = ?)) AND (workorders.application = ?)) AND 
(workorders.facility_id = ?) 

以上查詢應該給你相同的結果作爲您的原始查詢,但要少得多的努力。