MySQL非常慢的子查询优化

bl

我正在建立具有大量数据的sql查询,但查询速度太慢

我有3张桌子;moviesmovie_categoriesskipped_movies
movies表进行归一化,我试图查询基于一个类别,但排除ID的电影skipped_movies表。

但是,我试图在查询中使用WHERE IN和WHERE NOT IN。

movies表约。200万行(ID,姓名,分数)
movie_categories左右。500万个(id,movie_id,category_id)
skipped_movies大约有 1k行(id,movie_id,user_id)

skipped_movies表非常小10-20行时,查询会非常快。(大约40-50毫秒),但是当表获得1k左右的数据时,我在查询中得到7至8秒的时间。

这是我正在使用的查询。

SELECT SQL_NO_CACHE *从`movies` WHERE`id` IN(从`movie_id`从`movie_categories` WHERE`category_id` = 1)和`id` NOT IN(从``skipped_movies` WHERE`user_id` = 1选择SELECT`movie_id`) AND`score` <= 9 ORDER BY`score` DESC LIMIT 1;

我想过很多方法,但这是最快的方法。我什EXISTS至没有尝试过这种方法。

我正在使用SQL_NO_CACHE进行测试。

而且我猜想ORDER BY语句的运行速度非常慢。

spencer7593

假设(movie_id,category_id)在movies_categories表中是唯一的,我将使用联接操作而不是子查询来获得指定的结果。

为了排除“跳过”的电影,反连接模式就足够了……这是左外部连接,可在skipped_movies中找到匹配的行,然后在WHERE子句中使用谓词以排除找到的所有匹配项,仅保留未找到的匹配行有一场比赛。

SELECT SQL_NO_CACHE m.*
  FROM movies m
  JOIN movie_categories c 
    ON c.movie_id = m.id 
   AND c.category_id = 1
  LEFT
  JOIN skipped_movies s
    ON s.movie_id = m.id
   AND s.user_id = 1
 WHERE s.movie_id IS NULL
   AND m.score <= 9
 ORDER
    BY m.score DESC
 LIMIT 1

适当的索引可能会改善性能...

... ON movie_categories (category_id, movie_id)
... ON skipped_movies (user_id, movie_id)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章