我有三个 MySQL 表; “teams”和两个表,具体取决于团队类型(“team_type_1”和“team_type_2”)。我需要将所有三个表查询到一个表中,并将两个 team_type 表中每个团队的英里数汇总到一个“英里”列中。
下面的查询可以根据需要工作,但由于我的 JOIN 查询不使用主 ID,它要么锁定,要么花费太长时间。
在 JOIN 中使用主 ID“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
将上表合并为: 团队名称 |英里
当使用主键单独运行这些查询时,只需要几毫秒,但我需要组合这些表:
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 秒,但内部选择使用非主 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.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 提示,除了上面的几列和三个表之外,我还有正在查询的其他表和列,但没有提及这些,因为我可以使用主 ID对于那些。下面是我使用 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
最佳答案
有几种方法可以解决这个问题,但最简单的解决方案就是简单地 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
关于php - SQL LEFT JOIN 不使用主键的查询太慢,如何加快速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55055902/