假设我们有一个数据库,记录用户尚未评级的所有电影。每个评级都记录在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查询,但还有其他什么吗?有什么办法可以用不同的方式设计这个数据库吗?
答案 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)