所以我有2个表,一个叫user
,一个叫user_favorite
。 user_favorite
存储itemId
和userId
,用于存储用户已收藏的项目。我只是想找到不在user_favorite
中有记录的用户,这样我就可以找到那些尚未收藏任何内容的用户。
出于测试目的,我在user
中有6001条记录,在user_favorite
中有6001条记录,所以只有一条记录没有任何收藏。
这是我的疑问:
SELECT u.* FROM user u
JOIN user_favorite fav ON u.id != fav.userId
ORDER BY id DESC
这里最后一个语句中的id
不是ambigious,它指的是user
表中的id。我在u.id
上有一个PK索引,在fav.userId
上有一个索引。
当我运行此查询时,我的计算机变得没有响应并完全冻结,没有给出任何输出。我有2GB的RAM,不是一台好的计算机,但我认为它应该能够轻松处理6k记录这样的查询。
这两个表都在MyISAM中,这可能是问题吗?转换到INNODB会修复吗?
答案 0 :(得分:3)
让我们首先讨论您的查询(正如所写)正在做什么。由于on-子句中的!=,您将使用其他每个用户的收藏夹加入每个用户记录。因此,您的查询将生成类似36M行的内容。这不会给你你想要的答案。它解释了为什么你的电脑不满意。
您应该如何编写查询?您可以使用三种主要模式。我认为这是一个非常好的解释:http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/并且特别在mysql的上下文中讨论了性能。它向您展示了如何查看和阅读执行计划,这对优化查询至关重要。
答案 1 :(得分:1)
将您的查询更改为以下内容:
select * from User
where not exists (select * from user_favorite where User.id = user_favorite.userId)
让我知道它是怎么回事
答案 2 :(得分:1)
A != B
上的联接意味着A的每个记录都与B的每个记录连接在一起,其中id不相等。
换句话说,不是产生6000行,而是产生大约3600万(6000 * 6001)行的输出,所有这些都必须被收集,然后排序......