不使用主键的SQL LEFT JOIN查询太慢,如何加快速度?

时间:2019-03-08 02:33:11

标签: php mysql join union

我有三个MySQL表; “团队”和两个表(取决于团队类型)(“ team_type_1”和“ team_type_2”)。我需要将所有三个表查询到一个表中,并将每个team_mile从两个team_type表中汇总到一个“ miles”列中。

我下面的查询可以根据需要工作,但是由于我的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

将以上表格合并为: 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秒钟,但内部选择使用的是非主要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

2 个答案:

答案 0 :(得分:2)

有几种解决方法,但是最简单的解决方案是简单地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

答案 1 :(得分:0)

我有同样的问题。就我而言,我将列(非主列)从非唯一索引更改为唯一索引。它使我的查询速度提高了3倍。希望对别人有帮助。