Asis
Asis

Reputation: 303

Following query taking too long to execute. How to optimize it

I use the following query to get years and the number of movies released in that year which(referring to a movie) has a female actor.

It executes successfully, but it is taking 4 minutes to execute.
How do I get results in less time?

Also, my disk use goes to more than 70% during this execution.

SELECT m.year, COUNT(m.id)
FROM movies m
JOIN roles r ON m.id=r.movie_id
JOIN actors a ON r.actor_id=a.id
WHERE a.gender='F'
GROUP BY m.year;

Upvotes: 0

Views: 170

Answers (2)

Paul Spiegel
Paul Spiegel

Reputation: 31832

Your query is perfectly fine, if it returns the desired result. I've imported the imdb.sql and your query executes in 17 seconds on my PC. The EXISTS solution from the other answer needs 48 seconds and returns a different result.

The original tabes are using the MyISAM engine and are quite poorly indexed. After converting the three tables to InnoDB, your query executes in 2.3 seconds. InnoDB takes about twice as much space - But I think it's worth the performance boost.

Then the following changes

ALTER TABLE `actors` ADD INDEX `gender` (`gender`);

ALTER TABLE `roles`
    DROP INDEX `idx_actor_id`,
    ADD INDEX `idx_actor_movie` (`actor_id`, `movie_id`);

decreased the execution time to 1.7 seconds. That is 10 times faster than with the original schema.

Upvotes: 1

Naveen Kumar
Naveen Kumar

Reputation: 2006

I think you can use

EXISTS

instead of JOIN.

SELECT m.year, COUNT(m.id) FROM movies m 
where 
exists (select * from roles r where r.movie_id=m.id and 
exists(select * from actors a where a.id=r.actor_id and a.gender='F'))
group by  m.year;

To display Total Movies Per Year along with above output.

select t1.year,t1.count,t2.total from 
(
SELECT m.year as year, COUNT(m.id) as count FROM movies m 
where exists (select * from roles r where r.movie_id=m.id and exists(select * from actors a where a.id=r.actor_id and a.gender='F'))
group by  m.year
)t1 
join
(select year,count(m.id) as total from movies m group by m.year) t2
on t1.year=t2.year;

Upvotes: 3

Related Questions