У меня есть три таблицы MySQL; "teams" и две таблицы в зависимости от типа команды ("team_type_1" и "team_type_2"). Мне нужно запросить все три таблицы в одну таблицу и суммировать мили каждой команды из обеих таблиц team_type в один столбец «мили».
Мои запросы ниже работают по мере необходимости, но поскольку мои запросы JOIN не используют первичные идентификаторы, они либо блокируются, либо занимают слишком много времени.
Было бы неплохо использовать первичные идентификаторы «team_type_1.id» и «team_type_2.id» в JOIN, но моя попытка в последнем запросе ниже по-прежнему использует непервичные ключи во внутренних запросах. Есть ли другой подход, который я мог бы использовать для ускорения запроса?
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
Объедините приведенные выше таблицы в: имя_команды | мили
При выполнении этих запросов по отдельности с использованием первичных ключей это занимает всего миллисекунды, но мне нужно объединить эти таблицы:
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
@Strawberry А, я долгое время работал с UNIONS, но я также присоединяюсь к другим таблицам вместе с другими столбцами и продолжаю получать ошибку типа «Столбцы не совпадают». Однако вы подали мне идею, и я разместил обновление выше, используя UNIONS, которое выглядит так, как мне нужно, и очень быстро. Спасибо за подсказку.






Есть несколько способов обойти это, но самое простое решение — просто показатель столбец 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
Спасибо, но извините, miles — это поля формы расчета, которые заполняют эти столбцы и являются текстовыми типами, и не могут сделать их индексами для проверки вашего предложения.
Я была такая же проблема. В моем случае я изменил столбец (не основной) с неуникального индекса на уникальный индекс. Это ускорило мой запрос в 3 раза. Надеюсь, кому-то поможет.
Я не понимаю, почему вы присоединяетесь, а не объединяете два запроса. См. meta.stackoverflow.com/questions/333952/…