MySQL:查找不参与关系的行
我有两张桌子:“电影”和“用户”。 这两者之间存在n:m关系,描述了用户看过的电影。这是用一个表“SEED”来描述的 现在我想找出一个给定的用户,所有他没有看过的电影。 我目前的解决方案如下:MySQL:查找不参与关系的行,sql,mysql,join,entity-relationship,Sql,Mysql,Join,Entity Relationship,我有两张桌子:“电影”和“用户”。 这两者之间存在n:m关系,描述了用户看过的电影。这是用一个表“SEED”来描述的 现在我想找出一个给定的用户,所有他没有看过的电影。 我目前的解决方案如下: SELECT * FROM movies WHERE movies.id NOT IN ( SELECT seen.movie_id FROM seen WHERE seen.user_id=123 ) 这很好,但似乎不能很好地扩展。有更好的方法吗?您的查询不仅可以工
SELECT *
FROM movies
WHERE movies.id NOT IN (
SELECT seen.movie_id
FROM seen
WHERE seen.user_id=123
)
这很好,但似乎不能很好地扩展。有更好的方法吗?您的查询不仅可以工作,而且是解决上述问题的正确方法。也许你能找到一种不同的方法来解决这个问题?例如,即使对于大型表,对外部选择的简单限制也应该非常快。看到的是您的联接表,因此是的,这看起来是正确的解决方案。您实际上是从电影总数中减去为用户观看的电影ID集,从而为该用户生成未观看的电影 这被称为负连接,遗憾的是不在或不存在是最好的选择。我希望看到一种类似于内部/外部/左/右连接的负连接语法,但是ON子句可以是减法语句
@Bill没有子查询的解决方案应该是可行的,尽管正如他所指出的,从两个方面测试解决方案的性能是一个好主意。我怀疑子查询与否,整个SEEN.ID索引,当然还有整个MOVIE.ID索引都将以两种方式进行评估:这将取决于优化器如何从那里处理它。如果您的DBMS支持位图索引,您可以尝试使用它们。下面是一种典型的方法来执行此查询,而不使用您展示的子查询方法。这可能满足@Godeke查看基于连接的解决方案的请求
SELECT *
FROM movies m
LEFT OUTER JOIN seen s
ON (m.id = s.movie_id AND s.user_id = 123)
WHERE s.movie_id IS NULL;
但是,在大多数品牌的数据库中,此解决方案的性能可能比子查询解决方案差。最好使用EXPLAIN来分析这两个查询,看看在给定模式和数据的情况下哪一个查询做得更好
下面是子查询解决方案的另一个变体:
SELECT *
FROM movies m
WHERE NOT EXISTS (SELECT * FROM seen s
WHERE s.movie_id = m.id
AND s.user_id=123);
这是一个相关子查询,必须为外部查询的每一行计算它。通常这是昂贵的,而您的原始示例查询更好。另一方面,在MySQL中不存在往往比列中不存在好
同样,您必须测试每个解决方案并比较结果以确定。选择任何解决方案而不衡量性能都是浪费时间。他将问题标记为“mysql”。MySQL不支持位图索引。哎呀,我没有看标签。:>这很好,但似乎不能很好地扩展。有没有更好的方法?您是否在此查询上尝试了>?如果扩展不好,则索引无效。你的索引是什么?我一直忘了这个外部连接技巧。谢谢