SQL на нескольких соединениях слишком медленно - PullRequest
0 голосов
/ 04 мая 2020

У меня проблема с очень медленным запросом. Когда я удаляю из запроса activity_tracker или registration_statuses, запрос выполняется быстрее (3-4 секунды).

activity_tracker - ~ 300 000rows

registration_statuses - ~ 300 000rows

пользователей - ~ 32000rows

select users.name as 'Agent',
count(registration_statuses.id ) as 'Odoslané na DÚ',
count( registration_statuses.id ) as 'Uzatvorené',
count(activity_tracker.id) as 'Akcia vyhľadávania',
count(activity_tracker.id) as 'Otvorenie zložky',
count(activity_tracker.id) as 'Úprava/Uloženie zložky',
count(activity_tracker.id) as 'Zmena stavu zložky',
count(activity_tracker.id) as 'Pridanie aktualizácie zložky',
count(activity_tracker.id) as 'Pridanie poznámky zložky' 
from `users` 
left join `activity_tracker` on `users`.`id` = `activity_tracker`.`user_id` 
left join `registration_statuses` on `users`.`id` = `registration_statuses`.`created_by` 
inner join `role_user` on `users`.`id` = `role_user`.`user_id` 
where `role_user`.`role_id` <> 4 
  and (`registration_statuses`.`created_at` between '1970-01-01' and '2022-08-08') 
group by users.name

Есть вывод из Explain

1   SIMPLE  role_user               range   PRIMARY,role_user_role_id_foreign           role_user_role_id_foreign                     4     NULL                95      Using where; Using index; Using temporary; Using f...
1   SIMPLE  users                   eq_ref  PRIMARY                                     PRIMARY                                       4     role_user.user_id   1   
1   SIMPLE  registration_statuses   ref     registration_statuses_created_by_foreign    registration_statuses_created_by_foreign      5     role_user.user_id   1889    Using where
1   SIMPLE  activity_tracker        ref     activity_tracker_user_id_foreign            activity_tracker_user_id_foreign              4     role_user.user_id   3004    Using index

1 Ответ

0 голосов
/ 05 мая 2020

Пожалуйста, проверьте этот запрос

SELECT 

id,
name AS 'Agent',
SUM(registration_statuses_value_1) AS 'Odoslané na DÚ',
SUM(registration_statuses_value_2) AS 'Uzatvorené',
SUM(activity_tracker_value_1) AS 'Akcia vyhľadávania',
SUM(activity_tracker_value_2) AS 'Otvorenie zložky',
SUM(activity_tracker_value_3) AS 'Úprava/Uloženie zložky',
SUM(activity_tracker_value_4) AS 'Zmena stavu zložky',
SUM(activity_tracker_value_5) AS 'Pridanie aktualizácie zložky',
SUM(activity_tracker_value_6) AS 'Pridanie poznámky zložky' 

FROM
(
    (
        SELECT 
            users.id,
            users.name, -- AS 'Agent',
            COUNT(registration_statuses.id) AS registration_statuses_value_1, -- 'Odoslané na DÚ',
            COUNT(registration_statuses.id) AS registration_statuses_value_2, -- 'Uzatvorené',
            0 AS activity_tracker_value_1, -- 'Akcia vyhľadávania',
            0 AS activity_tracker_value_2, -- 'Otvorenie zložky',
            0 AS activity_tracker_value_3, -- 'Úprava/Uloženie zložky',
            0 AS activity_tracker_value_4, -- 'Zmena stavu zložky',
            0 AS activity_tracker_value_5, -- 'Pridanie aktualizácie zložky',
            0 AS activity_tracker_value_6 -- 'Pridanie poznámky zložky' 
        FROM `users`
        LEFT JOIN `registration_statuses` ON `users`.`id` = `registration_statuses`.`created_by` 
        INNER JOIN `role_user` ON `users`.`id` = `role_user`.`user_id` 
        WHERE `role_user`.`role_id` <> 4 AND (`registration_statuses`.`created_at` BETWEEN '1970-01-01' AND '2022-08-08') 
        GROUP BY users.id
    )
    UNION
    (
        SELECT
            users.id,
            users.name, -- AS 'Agent',
            0 AS registration_statuses_value_1, -- 'Odoslané na DÚ',
            0 AS registration_statuses_value_2, -- 'Uzatvorené',
            count(activity_tracker.id) AS activity_tracker_value_1, -- 'Akcia vyhľadávania',
            count(activity_tracker.id) AS activity_tracker_value_2, -- 'Otvorenie zložky',
            count(activity_tracker.id) AS activity_tracker_value_3, -- 'Úprava/Uloženie zložky',
            count(activity_tracker.id) AS activity_tracker_value_4, -- 'Zmena stavu zložky',
            count(activity_tracker.id) AS activity_tracker_value_5, -- 'Pridanie aktualizácie zložky',
            count(activity_tracker.id) AS activity_tracker_value_6 -- 'Pridanie poznámky zložky' 
        FROM `users` 
        LEFT JOIN `activity_tracker` ON `users`.`id` = `activity_tracker`.`user_id` 
        LEFT JOIN `registration_statuses` ON `users`.`id` = `registration_statuses`.`created_by` 
        INNER JOIN `role_user` ON `users`.`id` = `role_user`.`user_id` 
        WHERE `role_user`.`role_id` <> 4 AND (`registration_statuses`.`created_at` BETWEEN '1970-01-01' AND '2022-08-08') 
        GROUP BY users.id
    )
) AS `d`
GROUP BY `id`

UPD : заменить последнее соединение подзапросом

SELECT `users`.`name` AS 'Agent',
COUNT( `registration_statuses`.`id` ) AS 'Odoslané na DÚ',
COUNT( `registration_statuses`.`id` ) AS 'Uzatvorené',
COUNT( `activity_tracker`.`id` ) AS 'Akcia vyhľadávania',
COUNT( `activity_tracker`.`id` ) AS 'Otvorenie zložky',
COUNT( `activity_tracker`.`id` ) AS 'Úprava/Uloženie zložky',
COUNT( `activity_tracker`.`id` ) AS 'Zmena stavu zložky',
COUNT( `activity_tracker`.`id` ) AS 'Pridanie aktualizácie zložky',
COUNT( `activity_tracker`.`id` ) AS 'Pridanie poznámky zložky' 
FROM `users` 
LEFT JOIN `activity_tracker` ON `users`.`id` = `activity_tracker`.`user_id` 
LEFT JOIN `registration_statuses` ON `users`.`id` = `registration_statuses`.`created_by` 
WHERE 
  `registration_statuses`.`created_at` BETWEEN '1970-01-01' AND '2022-08-08'
  AND `users`.`id` IN (SELECT `user_id`  FROM `role_user` WHERE `role_id` <> 4 )
GROUP BY `users`.`id`
...