0

我有一个 SQL 查询需要 3.5 秒才能返回计数。查看查询的跟踪,看起来所有索引都在使用。我能做些什么来优化它以合理执行?

提前致谢。


链接到跟踪

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 = ?))

持续时间 3,791 ms 查询分析(显示详细信息)

Trace * workorders *
使用此索引检索表:facility_id,app_fac,workorder_status_id 您可以通过仅查询索引内的字段来加快此查询。或者,您可以创建一个包含查询中每个字段的索引,包括主键。

扫描了该表的大约 33850 行。

users
使用以下索引检索表:PRIMARY 扫描了该表的大约 1 行。

assets
该表是使用以下索引检索的:PRIMARY

扫描了该表的大约 1 行。

completed_by_users_workorders
使用以下索引检索表:PRIMARY

扫描了该表的大约 1 行。

消息
使用此索引检索表:workorder_id

扫描了该表的大约 2 行。

优先级
使用以下索引检索表:PRIMARY

扫描了该表的大约 1 行。

suspend_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 行。

4

1 回答 1

2

除非我遗漏了一些东西,否则你会有一堆LEFT JOIN不影响最终结果的 s (你正在选择distinct workorders.id- 我猜它是一个 PK 列。那么只有 where 很重要,WHERE ((((workorders.workorder_status_id = ?)) AND (workorders.application = ?)) AND (workorders.facility_id = ?)所以我相信你可以摆脱所有LEFT JOINs 并写只需从 1 个表中选择,使优化器的生活变得更加轻松......

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

上面的查询应该给您与原始查询相同的结果,但工作量要少得多。

于 2013-03-07T17:17:52.390 回答