我有两张桌子:'电影'和'用户'.这些之间存在n:m关系,描述用户看过的电影.这是用表'看'来描述的.现在我想找出给定用户,他没有看到的所有电影.我目前的解决方案是这样的:
SELECT * FROM movies WHERE movies.id NOT IN ( SELECT seen.movie_id FROM seen WHERE seen.user_id=123 )
这工作正常,但似乎没有很好的扩展.有更好的方法吗?
这是在不使用您显示的子查询方法的情况下执行此查询的典型方法.这可能会满足@ 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中" NOT EXISTS
"通常比" column NOT IN (...)
" 好"
同样,您必须测试每个解决方案并比较结果以确保. 在不衡量性能的情况下选择任何解决方案都是浪费时间.