【问题标题】:How can i speed up this django orm generated query?我怎样才能加快这个 django orm 生成的查询?
【发布时间】:2015-03-28 21:42:20
【问题描述】:

我有一个 Movie 表、一个 Genre 表和一个 MovieGenre 表来说明电影有哪些类型。

当我试图获取至少具有目标电影共有的所有类型的电影时,django orm 提出了这个查询。

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

【问题讨论】:

  • 也许非规范化计数并将它们存储在表中并在每次添加内容时更新它们,从而使查找计数成为更简单的 SELECT 操作?
  • @MikkoOhtamaa 你是说有另一个包含列、targetmovie、movie、genreinCommonCount 的表。如果是这样,那么对于每个 targetmovie/movie 组合,该表将是巨大的(100+ 百万行)。

标签: python django postgresql


【解决方案1】:

不是 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" )

说为 where 子句的列添加索引怎么样?我特别关注这些看起来不错的索引候选者:

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

【讨论】:

  • 我应该提到我在 movie.type 和 movie.certification 上有索引
【解决方案2】:

问题是我的 SELECT 不够具体

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

我选择了电影表中的每一列,有些列包含大量数据。使用 djanog 的 queryset .only() 方法更改此设置后,时间从 1000 毫秒降至 200 毫秒。一个好的开始

编辑:

它实际上是一个包含大量数据的字段,因此真正的解决方案是将其放在自己的表中。

【讨论】:

    猜你喜欢
    • 2021-08-01
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多