2015-03-28 4 views
2

У меня есть таблица фильмов и таблица жанров и таблица MovieGenre, чтобы сказать, в каких жанрах есть фильм.Как я могу ускорить этот запрос, созданный orm-django?

Орден django придумал этот вопрос, когда я пытаюсь получить фильмы, у которых есть, по крайней мере, все жанры, которые имеет целевой фильм.

SELECT "movies_movie"."id", "movies_movie"."imdb_id", ..etc.. "movies_movie"."last_ingested_on", 
COUNT("movies_movie"."id") AS "count", 
COUNT("movies_moviegenre"."genre_id") AS "genres_count" 
FROM "movies_movie" 
LEFT OUTER JOIN "movies_moviegenre" ON ("movies_movie"."id" = "movies_moviegenre"."movie_id") INNER JOIN "movies_moviegenre" T4 ON ("movies_movie"."id" = T4."movie_id") 
INNER JOIN "movies_moviegenre" T6 ON ("movies_movie"."id" = T6."movie_id") 
WHERE ("movies_movie"."last_ingested_on" IS NOT NULL 
AND NOT ("movies_movie"."imdb_id" = 'tt0111161') 
AND "movies_movie"."type" = 'feature' 
AND "movies_movie"."certification" = 'R' 
AND T4."genre_id" = 1 AND T6."genre_id" = 10) 
GROUP BY "movies_movie"."id", "movies_movie"."imdb_id", "movies_movie"."movie", "movies_movie"."type", "movies_movie"."year", "movies_movie"."tagline", "movies_movie"."plot", "movies_movie"."runtime", "movies_movie"."rating", "movies_movie"."certification", "movies_movie"."budget", "movies_movie"."box_office_revenue", "movies_movie"."poster_url", "movies_movie"."trailer_url", "movies_movie"."mood_data", "movies_movie"."created_on", "movies_movie"."modified_on", "movies_movie"."last_ingested_on" HAVING COUNT("movies_moviegenre"."genre_id") >= 2 
ORDER BY "count" DESC  

Вы можете видеть все, что может быть причиной его быть медленным, это занимает 1107.26499557 мс, который не является приемлемым. Заранее спасибо

объясняют вывод: http://explain.depesz.com/s/lEv

+0

Возможно, денормализовать подсчеты и сохранить их в таблицах и обновить их каждый раз, когда будет добавлен контент, и, таким образом, просмотр подсчета будет более простой операцией SELECT? –

+0

@ Микко Охтамаа, вы говорите, есть еще один стол со столбцами, целевое, кино, genreInCommonCount. Если это так, что таблица будет массивной (100+ миллионов строк) для каждой комбинации targetmovie/movie. – MrQuest98

ответ

0

не эксперт SQL, но это двойное внутреннее соединение выглядит странно для меня, как ни странно, в них эквивалентны.

LEFT OUTER JOIN "movies_moviegenre" ON ("movies_movie"."id" = "movies_moviegenre"."movie_id") INNER JOIN "movies_moviegenre" T4 ON ("movies_movie"."id" = T4."movie_id") INNER JOIN "movies_moviegenre" T6 ON ("movies_movie"."id" = T6."movie_id")

Сказала, что о добавлении индекса для столбцов вашей ИНЕКЕ? Я смотрю на них, в частности, которая выглядит как хорошие кандидаты индекса:

AND "movies_movie"."type" = 'feature' AND "movies_movie"."certification" = 'R' AND T4."genre_id" = 1 AND T6."genre_id" = 10)

См https://docs.djangoproject.com/en/1.7/topics/db/optimization/#use-standard-db-optimization-techniques

+0

Я должен был упомянуть, что у меня есть указатели на movie.type и movie.certification – MrQuest98

0

Проблема заключалась в том, я не был достаточно конкретным в моей SELECT,

SELECT "movies_movie"."id", "movies_movie"."imdb_id", ..etc.. 

я выбирал каждый столбец в таблице фильмов, некоторые столбцы содержат много данных. после изменения этого значения с помощью параметра queryset .nly() djanog время отбрасывается с 1000 мс до 200 мс. хорошее начало

редактировать:

это было одно поле с много данных в нем на самом деле, поэтому реальное решение положить, что в своей таблице.