首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mysql非常慢的子查询优化

Mysql非常慢的子查询优化
EN

Stack Overflow用户
提问于 2014-12-29 21:30:48
回答 3查看 358关注 0票数 2

我正在用大量数据构建sql查询,但是查询太慢了。

我有三张桌子:moviesmovie_categoriesskipped_movies

movies表是规范化的,我试图根据类别查询电影,同时从skipped_movies表中排除ids。

然而,我试图在我的查询中使用WHERE IN和NOT。

movies表大约有。200万行(id、name、score)

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秒的数据。

这是我正在使用的查询。

选择SQL_NO_CACHE *从movies id IN (从movie\_categories选择movie\_id category\_id = 1)和id NOT IN (从skipped\_movies选择user\_id = 1)和score <= 9按score DESC限制1的顺序选择;

我试过很多方法,但这是最快的方法。我甚至没有在任何程度上尝试过EXISTS方法。

我使用SQL_NO_CACHE只是为了测试。

我猜按规定订货的速度很慢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-12-29 21:37:33

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

为了排除“跳过”的电影,反连接模式就足够了.这是一个左外部联接,用于在skipped_movies中查找匹配的行,然后在WHERE子句中使用一个谓词来排除找到的任何匹配项,只留下没有匹配的行。

代码语言:javascript
复制
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

适当的索引可能会提高性能..。

代码语言:javascript
复制
... ON movie_categories (category_id, movie_id)
... ON skipped_movies (user_id, movie_id)
票数 1
EN

Stack Overflow用户

发布于 2014-12-29 21:43:50

大多数IN/NOT IN查询可以使用JOIN/LEFT来表示,这通常提供最佳性能。

将查询转换为使用联接:

代码语言:javascript
复制
SELECT m.*
FROM movies m
JOIN movie_categories mc ON m.id = mc.movie_id AND mc.category_id = 1
LEFT JOIN skipped_movies sm ON m.id = sm.movie_id AND sm.user_id = 1
WHERE sm.movie_id IS NULL
AND score <= 9
ORDER BY score DESC
LIMIT 1
票数 1
EN

Stack Overflow用户

发布于 2014-12-29 21:34:49

你的询问似乎没问题。只是一个小小的需要。可以将*替换为表中的列/属性名称。它将使这个查询比以往任何时候都快。因为*操作真的很慢

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27696316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档