SQL LEFT JOIN Query без использования первичных ключей слишком медленный, как я могу ускорить?

У меня есть три таблицы 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

Я не понимаю, почему вы присоединяетесь, а не объединяете два запроса. См. meta.stackoverflow.com/questions/333952/…

Strawberry 08.03.2019 04:37

@Strawberry А, я долгое время работал с UNIONS, но я также присоединяюсь к другим таблицам вместе с другими столбцами и продолжаю получать ошибку типа «Столбцы не совпадают». Однако вы подали мне идею, и я разместил обновление выше, используя UNIONS, которое выглядит так, как мне нужно, и очень быстро. Спасибо за подсказку.

hominid4 08.03.2019 07:39
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
589
2

Ответы 2

Есть несколько способов обойти это, но самое простое решение — просто показатель столбец 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 — это поля формы расчета, которые заполняют эти столбцы и являются текстовыми типами, и не могут сделать их индексами для проверки вашего предложения.

hominid4 08.03.2019 07:57

Я была такая же проблема. В моем случае я изменил столбец (не основной) с неуникального индекса на уникальный индекс. Это ускорило мой запрос в 3 раза. Надеюсь, кому-то поможет.

Другие вопросы по теме