NOT IN查询有哪些替代方案?

时间:2014-03-31 17:09:05

标签: sql database performance

假设我们有一个数据库,记录用户尚未评级的所有电影。每个评级都记录在MovieRating表中。

当我们正在寻找电影用户#1234还没有看到:

SELECT * 
FROM Movies 
WHERE id NOT IN 
    (SELECT DISTINCT movie_id FROM MovieRating WHERE user_id = 1234);

随着MovieRating的大小增长,查询NOT IN会非常昂贵。假设MovieRatings可以有超过100,000行。

我的问题是什么是NOT IN查询的一些更有效的替代方案?我听说过LEFT OUTER JOIN而不是EXIST查询,但还有其他什么吗?有什么办法可以用不同的方式设计这个数据库吗?

3 个答案:

答案 0 :(得分:0)

这是一个模拟查询,因为我没有数据库来测试这个,但是以下的内容应该工作。

select m.* from Movies m
left join MovieRating mr on mr.user_id = 1234
where mr.id is null

应该根据用户ID将电影表加入电影评级表。然后where子句将查找空条目,这将是用户未评级的电影。

答案 1 :(得分:0)

你可以试试这个:

SELECT M.*
  FROM Movies as M
       LEFT OUTER JOIN 
       MovieRating as MR on M.id = MR.movie_id 
                        and MR.user_id = 1234
 WHERE M.id IS NULL

答案 2 :(得分:0)

如果必须这样做,使用WHERE NOT EXISTS()的相关子查询可能是最有效的,但您应该根据数据测试性能。

您可能还需要考虑在选择列表(不使用*)和仅获取TOP n行方面限制结果。也就是说,如果用户没有看过,你可能不需要100k +电影。您可能想要分页结果。

SELECT * 
  FROM Movies m
 WHERE NOT EXISTS (SELECT 1 
                     FROM MovieRating r 
                    WHERE user_id = 1234 
                      AND r.movie_id= m.movie_id)