2015-10-16 60 views
-1

我創建了一個數據庫來存儲電影數據。我的表如下:我可以改進我的電影選擇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

這個問題應該轉移到[數據庫管理員](http://dba.stackexchange.com/tour),它在這裏是無關緊要的。 –

回答

2

首先,在你的表上使用索引。在我看來,movieActor上有3個索引應該很有用。 MovieId - ActorID - MovieIdActorId。

第二次嘗試tu使用外鍵。這些有助於確定您的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關鍵字進行優化。它也可以幫助您創建正確的索引。