Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何使用大型IN子句优化此SQL查询?_Mysql_Sql - Fatal编程技术网

Mysql 如何使用大型IN子句优化此SQL查询?

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

我有一个相当复杂的操作,我试图只使用一个SQL查询来执行,但我不确定这是否比将其分解为n个查询更理想。基本上,我有一个名为“Users”的表,其中充满了用户id及其关联的fb_id(id是pk,fb_id可以为null)

我还有另一个名为“Friends”的表,它表示两个用户之间的朋友关系。这使用他们的ID(而不是他们的fb_ID),应该是一种双向关系

+----------------+
| 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