Mysql 如何使用大型IN子句优化此SQL查询?
我有一个相当复杂的操作,我试图只使用一个SQL查询来执行,但我不确定这是否比将其分解为n个查询更理想。基本上,我有一个名为“Users”的表,其中充满了用户id及其关联的fb_id(id是pk,fb_id可以为null) 我还有另一个名为“Friends”的表,它表示两个用户之间的朋友关系。这使用他们的ID(而不是他们的fb_ID),应该是一种双向关系Mysql 如何使用大型IN子句优化此SQL查询?,mysql,sql,Mysql,Sql,我有一个相当复杂的操作,我试图只使用一个SQL查询来执行,但我不确定这是否比将其分解为n个查询更理想。基本上,我有一个名为“Users”的表,其中充满了用户id及其关联的fb_id(id是pk,fb_id可以为null) 我还有另一个名为“Friends”的表,它表示两个用户之间的朋友关系。这使用他们的ID(而不是他们的fb_ID),应该是一种双向关系 +----------------+ | id | friend_id | |====|===========| | 0 | 1
+----------------+
| id | friend_id |
|====|===========|
| 0 | 1 |
| 1 | 0 |
| .. | .. |
+----------------+
// user 0 and user 1 are friends
问题是:
我们得到了一个特定用户的id(“我的id”)和该用户的Facebook好友数组(一个称为fb_数组的fb_id数组)。我们希望更新Friends表,以便将Facebook友谊视为用户之间的有效友谊。需要注意的是,并非所有Facebook好友都会在我们的数据库中拥有帐户,因此这些好友应该被忽略。该查询将在用户每次登录时调用,以便在用户在Facebook上添加新朋友时更新我们的数据。以下是我写的问题:
INSERT INTO Friends (id, friend_id)
SELECT "my_id", id FROM Users WHERE id IN
(SELECT id FROM Users WHERE fb_id IN fb_array)
AND id NOT IN
(SELECT friend_id FROM Friends WHERE id = "my_id")
第一个IN子句的要点是获取所有用户的子集,这些用户也是您的Facebook好友,这是我担心的主要部分。因为fb_id是作为一个数组给出的,所以我必须将所有id解析成一个巨大的字符串,由逗号分隔,组成“fb_数组”。我担心在IN子句中使用如此巨大的字符串的效率(一个用户在Facebook上可能有数百或数千个朋友)。您能想出更好的方法来编写这样的查询吗
同样值得注意的是,这个查询并没有保持朋友关系的双重性质,但这不是我所担心的(扩展它会很简单)。如果我没有弄错,您的查询可以简化,如果您对组合
(id,friend\u id)
有一个唯一的约束,则可以:
INSERT IGNORE INTO Friends
(id, friend_id)
SELECT "my_id", id
FROM Users
WHERE fb_id IN fb_array ;
您应该在用户(fb\u id,id)
上建立索引,并测试效率。如果数组中的ITME数量太大(超过几千个),您可能需要拆分数组并多次运行查询。使用数据和设置配置文件。取决于以下列是否可为空(值可以为NULL
):
- 用户id
- 朋友
可为空:
不可为空:
有关更多信息:
与数组中的值数有关
上述两篇文章中运行的测试包含100万行,有10000个不同的值。谢谢,这是一个很好的观点!但是考虑到fb_数组可能是一个包含数千个ID的列表,您对该查询的效率有何想法?也许我什么都不担心,我只是从来没有写过这样的查询。它们都不能为null。谢谢你的回复!也许这会有帮助。看起来IN子句的性能是您的最佳选择。我想说这只是一种情境。祝你好运
INSERT IGNORE INTO Friends
(id, friend_id)
SELECT "my_id", id
FROM Users
WHERE fb_id IN fb_array ;
SELECT DISTINCT
"my_id", u.id
FROM Users u
WHERE u.fb_id IN fb_array
AND u.id NOT IN (SELECT f.friend_id
FROM FRIENDS f
WHERE f.id = "my_id")
SELECT "my_id", u.id
FROM Users u
LEFT JOIN FRIENDS f ON f.friend_id = u.id
AND f.id = "my_id"
WHERE u.fb_id IN fb_array
AND f.fried_id IS NULL