我可以改进我的电影选择SQL查询

时间:2015-10-16 21:31:25

标签: mysql sql

我创建了一个存储电影数据的数据库。我的表格如下:

movies:

CREATE TABLE IF NOT EXISTS `movies` (
  `movieId` int(11) NOT NULL AUTO_INCREMENT,
  `imdbId` varchar(255) DEFAULT NULL,
  `imdbRating` float DEFAULT NULL,
  `movieTitle` varchar(255) NOT NULL,
  `movieLength` varchar(255) NOT NULL,
  `imdbRatingCount` varchar(255) NOT NULL,
  `poster` varchar(255) NOT NULL,
  `year` varchar(255) NOT NULL,
  PRIMARY KEY (`movieId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

我有一张表,其中存储了电影actors:

CREATE TABLE IF NOT EXISTS `actors` (
  `actorId` int(10) NOT NULL AUTO_INCREMENT,
  `actorName` varchar(255) NOT NULL,
  PRIMARY KEY (`actorId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

另外一个我存储电影和演员之间的关系:(movieActor)

CREATE TABLE IF NOT EXISTS `movieActor` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `movieId` int(10) NOT NULL,
  `actorId` int(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

现在,当我想选择所选演员的电影列表时,我的查询是:

SELECT *
FROM movies m inner join
(SELECT movieId FROM movieActor WHERE actorId IN(1,2,3) GROUP BY movieId having count(*) = 3) ma ON m.movieId = ma.movieId 
WHERE imdbRating IS NOT NULL ORDER BY imdbRating DESC

这很完美,但我不知道这是实现这一目标的最佳表结构和查询。是否有更好的表结构来存储数据或查询列表?

1 个答案:

答案 0 :(得分:2)

首先,在表上使用索引。在我看来,在movieActor上有3个索引应该是有用的。 MovieId - ActorID - MovieIdActorId。

第二次尝试使用外键。这些有助于确定dbs的最佳执行计划。

第三,尽量避免在查询的执行计划中生成临时表。子选择通常会创建临时表,当数据库必须临时将某些内容保存在RAM中时使用。要检查这一点,请在goer查询前写下EXPLAIN。

我会这样写:

SELECT m.*, movieActor
FROM movies m inner join
movieActor ma ON m.movieId = ma.movieId 
WHERE imdbRating IS NOT NULL 
  and actorId IN(1,2,3)
GROUP BY movieId 
having count(*) = 3) 
ORDER BY imdbRating DESC

(未经测试)

尝试使用EXPLAIN关键字进行优化。它还可以帮助您创建正确的索引。