SQL LEFT JOIN Запрос не использует первичные ключи слишком медленно, как я могу ускорить? - PullRequest
0 голосов
/ 08 марта 2019

У меня есть три таблицы MySQL;«команды» и две таблицы в зависимости от типа команды («team_type_1» и «team_type_2»).Мне нужно запросить все три таблицы в одну таблицу и суммировать мили каждой команды из обеих таблиц team_type в один столбец «миль».

Мои запросы ниже работают по мере необходимости, но поскольку мои запросы JOIN не выполняютсяt с использованием основных идентификаторов он либо блокируется, либо занимает слишком много времени.

Было бы хорошо использовать основные идентификаторы "team_type_1.id" и "team_type_2.id" в соединениях, но моя попытка в последнем запросе нижевсе еще используя неосновные ключи во внутренних запросах.Могу ли я использовать другой подход для ускорения запроса?

Table 1: teams (3000 total records)
id (primary) | team_name


Table 2: team_type_1 (12000 total records)
id (primary) | team_id | miles


Table 3: team_type_2 (150000 total records)
id (primary) | team_id | miles

Объедините приведенные выше таблицы в: team_name |миль


При выполнении этих запросов отдельно с использованием первичных ключей это занимает всего миллисекунды, но мне нужно объединить эти таблицы:

SELECT
teams.team_name,
SUM(team_type_1.miles)
FROM team_type_1
LEFT JOIN teams ON teams.id = team_type_1.team_id
GROUP BY team_type_1.team_id


SELECT
teams.team_name,
SUM(team_type_2.miles)
FROM team_type_2
LEFT JOIN teams ON teams.id = team_type_2.team_id
GROUP BY team_type_2.team_id

При объединении, а не при использовании первичных ключей, он блокирует базу данных:

SELECT
teams.team_name,
SUM(CASE WHEN team_type_2.miles THEN team_type_2.miles ELSE team_type_1.miles END)
FROM teams

LEFT JOIN team_type_1 ON team_type_1.team_id = teams.id
LEFT JOIN team_type_2 ON team_type_2.team_id = teams.id

GROUP BY teams.id

Это занимает около 8-10 секунд, но внутренний выбор использует неосновные идентификаторы;Есть ли способ ускорить это?

SELECT
teams.team_name,
SUM(CASE WHEN team_type_2.miles THEN team_type_2.miles ELSE team_type_1.miles END)
FROM teams

LEFT JOIN team_type_1 ON team_type_1.id = (SELECT team_type_1.id FROM team_type_1 WHERE team_type_1.team_id = teams.id GROUP BY team_type_1.team_id)
LEFT JOIN team_type_2 ON team_type_2.id = (SELECT team_type_2.id FROM team_type_2 WHERE team_type_2.team_id = teams.id GROUP BY team_type_2.team_id)

WHERE team_type_2.miles > 0 OR team_type_1.miles > 0 GROUP BY teams.id

  • ОБНОВЛЕНИЕ:

Спасибо @Strawberry за подсказку UNION, кроме того, несколько столбцов итри таблицы выше, у меня также были другие таблицы и столбцы, к которым я обращаюсь, но я не упомянул их, так как я могу использовать первичные идентификаторы для них.Ниже приведена моя полная структура запросов, использующая UNIONS, и она работает так, как мне нужно.

SELECT
teams.team_name,
teams.start_date,
team_counties.county_name,
team_leagues.league_name,
SUM(team_type_1.miles)
FROM team_type_1

LEFT JOIN teams ON teams.id = team_type_1.team_id
LEFT JOIN team_counties ON team_counties.id = teams.county_id
LEFT JOIN team_leagues ON team_leagues.id = teams.league_id

GROUP BY team_type_1.team_id

UNION

SELECT
teams.team_name,
teams.start_date,
team_counties.county_name,
team_leagues.league_name,
SUM(team_type_2.miles)
FROM team_type_2

LEFT JOIN teams ON teams.id = team_type_2.team_id
LEFT JOIN team_counties ON team_counties.id = teams.county_id
LEFT JOIN team_leagues ON team_leagues.id = teams.league_id

GROUP BY team_type_2.team_id

1 Ответ

2 голосов
/ 08 марта 2019

Есть несколько способов обойти это, но самое простое решение - просто index team_id столбец в двух вложенных таблицах:

ALTER TABLE `team_type_1`
    ADD INDEX `team_id` (`team_id`);
ALTER TABLE `team_type_2`
    ADD INDEX `team_id` (`team_id`);

Это должно позволить вамсделать с некоторой скоростью следующее:

SELECT teams.id,
       teams.team_name,
       SUM(IFNULL(team_type_1.miles, 0) + IFNULL(team_type_2.miles, 0)) sum_miles
FROM teams
LEFT JOIN team_type_1 ON team_type_1.team_id = teams.id
LEFT JOIN team_type_2 ON team_type_2.team_id = teams.id
GROUP BY teams.id,
         teams.team_name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...