此问题适用于任何包含项目的系统(例如:新闻文章)和观看这些项目的用户。
因此,假设我有一个用户表([id],[username])
,一个文章表([id],[title],[text])
以及一个包含所有用户([user_id],[article_id])
查看的所有文章的表。
我想要做的是有效地向用户显示他之前没有读过的文章。
我知道我可以做一些像
这样的事情select id,title,text from articles where id not in (select article_id
from article_views where user_id = 123)
但是,如果当前用户已阅读1M文章怎么办?查询将变为类似
select id,... from articles where id not in (1,2,3,......1000000)
我可以假设,这太慢而不实用。
此外,它很糟糕,因为用户阅读的文章越多 - 他将检索新(未读)文章的响应时间越慢。
其他任何建议,db-wise?
答案 0 :(得分:1)
不是直接将它们添加到语句中,而是运行类似:
select articles.id, ... from articles, article_views where article_views.user_id = [useridhere] and articles.id != article_views.id
它减轻了查询的问题,但如果您有一百万篇文章,那么您仍在比较一百万篇文章。
答案 1 :(得分:1)
有时,通过执行LEFT JOIN并且仅返回NULL(即:未找到)条目可能比子选择更快。这是直接加入A:B并且仅包括那些找不到匹配的那些
select
a.id,
a.title,
a.text
from
articles a
LEFT JOIN article_views av
on av.User_ID = 123
AND a.id = av.article_id
where
av.article_id IS NULL
我会确保(UserID,Article_ID)上的索引(我相信它仍然是你对该表的主键)。