サポートチケットシステムがあります。現在、ユーザーが複数の部門のメンバーになることができる部門セクションを追加しています。
問題は、サブクエリを使用して、そのユーザーの部門アクセステーブルにあるdepartment_idのチケットを取得していることです。
これはサブクエリです:
t.department_id IN (SELECT utd.department_id FROM users_to_departments utd WHERE utd.user_id = :department_or_assigned_or_user_id AND utd.site_id = :site_id)
これにより、クエリの速度が低下します。11万枚のチケットのテーブルには約2秒かかります。サブクエリが原因です。
それをLEFTJOINに変換してから、HAVING utd.id IS NOT NULLを使用してみましたが、速度が遅くなりました。
それを内部結合に変換できるかどうか疑問に思いました。
問題は、チケットが現在別の部門にある場合でも、そのユーザーによって作成されたチケットも常に取得したいということです。
現在、これを行うためにサブクエリの後に以下を使用しています。
OR (t.assigned_user_id = :department_or_assigned_or_user_id OR t.user_id = :department_or_assigned_or_user_id)
すべての正しい列にインデックスが付けられるため、MySQLはファイルソートなどを実行しません。
users_to_departmentsテーブルは、単にuser_idとdepartment_idです。
どんな助けでも素晴らしいでしょう。
これが私の完全なクエリです。
SELECT
t.* ,
u.pushover_key AS `owner_pushover_key`,
u.name AS `owner_name`,
u.id AS `owner_id`,
u.email AS `owner_email`,
u.phone_number AS `owner_phone`,
u.email_notifications AS `owner_email_notifications`,
u2.pushover_key AS `assigned_pushover_key`,
u2.name AS `assigned_name`,
u2.id AS `assigned_id`,
u2.email AS `assigned_email`,
u2.email_notifications AS `assigned_email_notifications`,
u3.name AS `submitted_name`,
u3.id AS `submitted_id`,
u3.email AS `submitted_email`,
u3.email_notifications AS `submitted_email_notifications`,
tp.name AS `priority_name`,
td.name AS `department_name`,
ts.name AS `status_name`,
ts.colour AS `status_colour`,
ts.active AS `active`,
pa.name AS `pop_account_name`
FROM
tickets t
LEFT JOIN users u ON u.id = t.user_id
LEFT JOIN users u2 ON u2.id = t.assigned_user_id
LEFT JOIN users u3 ON u3.id = t.submitted_user_id
LEFT JOIN ticket_priorities tp ON tp.id = t.priority_id
LEFT JOIN ticket_departments td ON td.id = t.department_id
LEFT JOIN ticket_status ts ON ts.id = t.state_id
LEFT JOIN pop_accounts pa ON pa.id = t.pop_account_id
WHERE
1 = 1
AND t.site_id = :site_id
AND (
t.department_id IN (SELECT utd.department_id FROM users_to_departments utd WHERE utd.user_id = :department_or_assigned_or_user_id AND utd.site_id = :site_id)
OR
(t.assigned_user_id = :department_or_assigned_or_user_id OR t.user_id = :department_or_assigned_or_user_id)
)
ORDER BY
t.last_modified DESC
LIMIT :limit OFFSET :offset
MySQL Explainの結果へのリンクは次のとおりです:http: //michaeldale.com.au/images/explain.html