加速:使用GROUP BY查询

时间:2015-05-29 11:58:37

标签: mysql sql database

我使用下面的查询来选择电影最小年龄的演员。

SELECT production_cast.production_id, MIN(birthdate) FROM person
LEFT JOIN production_cast ON production_cast.person_id = person.id
WHERE birthdate IS NOT NULL
GROUP BY production_cast.production_id;

然而,IMDB数据集非常庞大,完成时间超过300秒。没有GROUP BY和MIN,这个查询在0.2秒内工作:

SELECT production_cast.production_id FROM person
LEFT JOIN production_cast ON production_cast.person_id = person.id
WHERE birthdate IS NOT NULL;

数据库引擎是MyIsam。 Mysql版本是5.7.2。我尝试使用这些BTREE索引:

  • production_cast.production_id
  • person.birthdate
  • person.birthdate and person.id
  • production_cast.id和production_cast.production_id

解释的简要输出是: 人:范围, 索引: idx_Person_id_birthdate,idx_Person_id_birthdate, 额外:使用where;使用索引;使用临时;使用filesort

Production_cast:参考, 索引: idx_Production_cast_person_id_production_id 额外:使用索引

person.id和production_cast.id是主键索引。 production_cast.production_id不是主键,但有索引。我该怎么做才能提高此搜索查询的速度。

2 个答案:

答案 0 :(得分:1)

您可以添加一些索引来加速数据检索。

production_cast

  • person_id
  • id

person

  • id
  • birthdate

这样,数据库不需要检索所有数据,只需要检索索引中的数据。此外,索引列的顺序将加快检索速度。您还应该将person.birth_date列别名为解析时间:

SELECT pc.id
,      MIN(p.birthdate)
FROM   person p
LEFT 
JOIN   production_cast pc
ON     pc.person_id = p.id
WHERE  p.birthdate IS NOT NULL
GROUP
BY     pc.id;

答案 1 :(得分:1)

评论太长了。

首先,不需要LEFT JOIN,除非你关心的是没有任何制作演员的“人”。这似乎不太可能。所以,您的查询是:

SELECT p.id, MIN(birthdate)
FROM person p JOIN
     production_cast pc
     ON pc.person_id = p.id
WHERE p.birthdate IS NOT NULL
GROUP BY pc.id;

其次,如果production_cast.id是主键而person.id是主键,则查询无法为给定的production_cast.id生成重复值。因此,group by不是必需的:

SELECT p.id, p.birthdate
FROM person p JOIN
     production_cast pc
     ON pc.person_id = p.id
WHERE p.birthdate IS NOT NULL;

我怀疑您在production_cast中有另一个表或另一个聚合键,但您的查询没有按照您认为的那样做。