当我的数据库中只包含有限数量的朋友时,此查询过去非常快速地运行,但随着用户群的增长,我发现查询的指数速度会慢一些。
我的朋友表的架构如下:
friend_id - entity_id1 - entity_id2 - category
1 1 2 1
2 2 1 1
3 3 2 1
4 2 3 1
5 1 3 1
6 3 1 1
正如我们上面所看到的,每个朋友关联之间存在互惠关系,这是为了改善建议朋友的查询时间而实施的。
我现在正试图在我建议的朋友有效负载中返回共同的朋友,但是在while循环中为每个用户编译需要大约1秒的时间,而我目前只有2000个用户......这将是个大问题随着应用程序进一步扩展。
我目前使用的查询如下:
SELECT COUNT(*) AS mutual_count
FROM entity
WHERE EXISTS(
SELECT *
FROM friends
WHERE friends.Entity_Id1 = :friendId AND friends.Category <> 4
AND friends.Entity_Id2 = entity.Entity_Id
)
AND EXISTS(
SELECT *
FROM friends
WHERE friends.Entity_Id1 = :userId AND friends.Category <> 4
AND friends.Entity_Id2 = entity.Entity_Id
)
其中:userId是登录用户,而:friendId是我们想要获得共同朋友的用户。正如我所说,这个查询工作正常,但速度极慢,我该如何优化呢?
答案 0 :(得分:1)
您有两个重要的子查询,您可以选择它们中的所有列。 首先消除其中一个 - 尝试:
SELECT COUNT(*) AS mutual_count
FROM entity
WHERE (
SELECT COUNT(*) > 0
FROM friends
WHERE friends.Category <> 4 AND friends.Entity_Id2 = entity.Entity_Id
AND (friends.Entity_Id1 = :friendId AND friends.Entity_Id1 = :userId)
)
然后我建议使用内连接而不是子查询 - 可能是这样的:
SELECT COUNT(DISTINCT entity.id) AS mutual_count
FROM entity
INNER JOIN friends ON friends.Entity_Id2 = entity.Entity_Id
AND friends.Category <> 4
AND (friends.Entity_Id1 = :userId AND friends.Entity_Id1 = :friendId)
我没有检查它(我不知道表结构)因此可能存在一些语法错误 - 但我希望它会以某种方式帮助你。
答案 1 :(得分:1)
你所拥有的是2个相关的子查询,它们是你在mysql中可以获得的最快的查询,这两个子查询的最佳索引就是这个:
ALTER TABLE friends ADD KEY (Entity_Id1, Category, Entity_Id2)