0

カウントを返すのに3.5秒以上かかるSQLクエリがあります。クエリのトレースを見ると、すべてのインデックスが使用されているように見えます。これを合理的な実行に最適化するために何ができますか?

よろしくお願いします。


トレースへのリンク

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ミリ秒クエリ分析(詳細を表示)

Trace * workorders *
テーブルは次のインデックスで取得されました:facility_id、app_fac、workorder_status_idインデックス内のフィールドのみをクエリすることで、このクエリを高速化できます。または、主キーを含む、クエリのすべてのフィールドを含むインデックスを作成できます。

このテーブルの約33850行がスキャンされました。

users
テーブルは次のインデックスで取得されました。PRIMARYこのテーブルの約1行がスキャンされました。

アセット
テーブルは次のインデックスで取得されました:PRIMARY

このテーブルの約1行がスキャンされました。

complete_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 ((((workorders.workorder_status_id = ?)) AND (workorders.application = ?)) AND (workorders.facility_id = ?)。だから私はあなたがすべてのsを取り除きLEFT JOINそして書くことができると信じています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 に答える