Оптимизация запроса с множественным выбором в качестве столбцов - PullRequest
0 голосов
/ 09 июля 2020

У меня есть запрос, который я сделал:

 SELECT DISTINCT player_1 AS player, 
                (SELECT COUNT(*) FROM results WHERE player_1=player OR player_2=player) AS since_start_matches, 
                (SELECT COUNT(*) FROM results WHERE (player_1=player OR player_2=player) AND ht_total_goals=0) AS since_start_ht_0,
                (SELECT COUNT(*) FROM results WHERE (player_1=player OR player_2=player) AND ht_total_goals=1) AS since_start_ht_1,
                (SELECT COUNT(*) FROM results WHERE (player_1=player OR player_2=player) AND ht_total_goals=2) AS since_start_ht_2,
                (SELECT COUNT(*) FROM results WHERE (player_1=player OR player_2=player) AND ht_total_goals=3) AS since_start_ht_3,
                (SELECT COUNT(*) FROM results WHERE (player_1=player OR player_2=player) AND ht_total_goals=4) AS since_start_ht_4,
                (SELECT COUNT(*) FROM results WHERE (player_1=player OR player_2=player) AND ht_total_goals>=5) AS since_start_ht_5_plus
FROM results ORDER BY player

Таблица results содержит 25000 записей, и для выполнения этого запроса требуется около 7 секунд, что слишком долго. Запрос невероятно неэффективен, поскольку каждый создаваемый мной столбец снова выполняет поиск в той же таблице, но с другими условиями.

Я попытался проиндексировать интересующие столбцы в моем предложении where. Это сбивает пару секунд. Но он по-прежнему слишком медленный.

Как лучше всего обрабатывать такой запрос?

Я использую MariaDB 10.2

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Отверните данные, затем агрегируйте:

 SELECT player, 
        COUNT(*) AS since_start_matches, 
        SUM(ht_total_goals=0) AS since_start_ht_0,
        SUM(ht_total_goals=1) AS since_start_ht_1,
        SUM(ht_total_goals=2) AS since_start_ht_2,
        SUM(ht_total_goals=3) AS since_start_ht_3,
        SUM(ht_total_goals=4) AS since_start_ht_4,
        SUM( ht_total_goals>=5) AS since_start_ht_5_plus
FROM ((SELECT player_1 as player, ht_total_goals
       FROM results
      ) UNION ALL
      (SELECT player_2 as player, ht_total_goals
       FROM results
      )
     ) p
GROUP BY player
0 голосов
/ 09 июля 2020

Вы можете использовать LEFT JOIN и conditional aggregation следующим образом:

SELECT  player_1 AS player, 
                COUNT(T2.player_1) AS since_start_matches, 
                SUM(CASE WHEN T2.ht_total_goals=0 THEN 1 END) AS since_start_ht_0,
                SUM(CASE WHEN T2.ht_total_goals=1 THEN 1 END) AS since_start_ht_1,
                SUM(CASE WHEN T2.ht_total_goals=2 THEN 1 END) AS since_start_ht_2,
                SUM(CASE WHEN T2.ht_total_goals=3 THEN 1 END) AS since_start_ht_3,
                SUM(CASE WHEN T2.ht_total_goals=4 THEN 1 END) AS since_start_ht_4,
                SUM(CASE WHEN T2.ht_total_goals>=5 THEN 1 END) AS since_start_ht_5_PLUS
FROM results T1 LEFT JOIN results T2 
ON (T2.player_1=T.player OR T2.player_2=T.player)
GROUP BY T1.PLA

YER_1 ORDER BY player

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...