我创建了一个存储电影数据的数据库。我的表格如下:
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
这很完美,但我不知道这是实现这一目标的最佳表结构和查询。是否有更好的表结构来存储数据或查询列表?
答案 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关键字进行优化。它还可以帮助您创建正确的索引。