mysql - 我如何用一个大的 IN 子句优化这个 SQL 查询?

标签 mysql sql

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

+-----------------+
| id | .. | fb_id |
|====|====|=======|
| 0  | .. | 12345 |
| 1  | .. | 31415 |
| .. | .. |  ..   |
+-----------------+

我还有另一个名为“Friends”的表,表示两个用户之间的 friend 关系。这使用他们的 id(而不是他们的 fb_id)并且应该是双向关系。

+----------------+
| id | friend_id |
|====|===========|
| 0  |     1     |
| 1  |     0     |
| .. |    ..     |
+----------------+
// user 0 and user 1 are friends

问题来了: 我们获得了特定用户的 ID(“my_id”)和该用户的 Facebook 好友数组(称为 fb_array 的 fb_id 数组)。我们想更新 Friends 表,以便将 Facebook 友谊视为我们用户之间的有效友谊。请务必注意,并非他们所有的 Facebook 好友都会在我们的数据库中拥有帐户,因此应忽略这些好友。每次用户登录时都会调用此查询,以便在他们在 Facebook 上添加任何新 friend 时更新我们的数据。这是我写的查询:

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_ids 是作为数组给出的,所以我必须将所有 id 解析为一个由逗号分隔的巨大字符串,该字符串构成“fb_array”。我担心为该 IN 子句设置如此庞大的字符串的效率(用户可能在 Facebook 上有成百上千个 friend )。您能想出更好的方法来编写这样的查询吗?

同样值得注意的是,这个查询并没有保持 friend 关系的双重性质,但这不是我担心的(为此扩展它是微不足道的)。

最佳答案

如果我没记错的话,你的查询可以被简化,如果你对组合 (id, friend_id) 有一个 UNIQUE 约束,到:

INSERT IGNORE INTO Friends 
  (id, friend_id)
SELECT "my_id", id 
FROM Users 
WHERE fb_id IN fb_array ;

您应该在 User (fb_id, id) 上建立索引并测试效率。如果数组中的项目数太大(超过几千),您可能不得不拆分数组并多次运行查询。使用您的数据和设置进行配置。

关于mysql - 我如何用一个大的 IN 子句优化这个 SQL 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14149689/

相关文章:

MySQL 查询 ORDER BY DateTime 问题

mysql - 连接到数据库时未处理 SocketException

mysql - MySQL中VARCHAR(255)的存储大小是多少

mysql - 没有重复的 SQL INSERT(没有主键或唯一键)

MySQL 从 DENSE_RANK() 结果更新相同的表字段

mysql - SQL查询不返回表中的非唯一值

javascript - 创建一个可以离线工作、存​​储数据然后在在线时将其同步到远程 MySQL 的 Web 应用程序?

mysql - 拆分 SQL 语句

sql - 如何从 DDL 触发器获取 ALTER 之前的过程文本

php - MySQL PDO;从排序结果中获取行,并且它的位置唯一