我在一个mysql服务器上有一个朋友id, u1,
u2
和约< 500,000
条目的表格
我想拍摄userA
和userB
并检查他们是否有共同的朋友。
做得更快
select u2 from friends where u1 = userA and u2 IN (select u2 from friends where u1 = userB)
在图表上(在一台服务器上)运行最短路径算法?
标准方式是什么,像LinkedIn和Facebook这样的大型网络用来处理这个问题?
谢谢!
答案 0 :(得分:2)
如果表朋友被u1和u2索引,则SQL查询将采用两个子集的交集并且非常快。这是因为索引已经完成。如果你在内存中进行计算,时间取决于你是否有预建索引:如果你有,你会因为没有数据库连接开销而更快。如果索引包含在计算时间内,并且数据库已加热(内存中的所有数据),则可能会丢失。
我正在谈论索引,而不是最短路径算法,因为最短路径算法计算的数据量超出了你的需要。
答案 1 :(得分:2)
在MySQL中,您编写的查询将比查找此信息的任何其他方式慢。也许比单独询问每个人要慢。您的查询:
select u2
from friends
where u1 = userA and
u2 IN (select u2 from friends where u1 = userB)
IN子句中有子查询。 MySQL评估遇到的每一行的查询。写这个的更好方法是:
select u2
from friends
where u1 = userA and
exists (select 1 from friends where u1 = userB limit 1)
如果您的数据全部适合一台服务器并且适合内存,那么优化的MySQL查询的性能应该没问题。 LinkedIn和FaceBook等网站正在处理各种各样的问题 - 不断更新网络,大量数据,不同类型的链接等等。您的简单示例并不代表他们正在做的事情。但是,他们的许多分析都将Hadoop或Hadoop与关系数据库结合使用。
答案 2 :(得分:2)
在图表数据库中,您可以在gremlin中将查询编写为:
g.V('username','userB').out('friend').retain(g.V('username','userA').out('friend').gather)
大多数图表数据库应该快速执行。
如果您使用Titan,您还可以利用Titan按排序顺序维护相邻顶点,这意味着您只需对数据进行一次迭代即可计算两个朋友列表的交集,而无需创建其他数据结构。这可能比MySQL快,如果朋友的平均数量很大,速度要快得多。
答案 3 :(得分:0)
以下是使用简单inner join
:
select fA.u2
from friends fA
inner join friends fB on
fA.u2 = fB.u2
where fA.u1 = userA and
fB.u1 = userB
这与多对多类型查询的方法相同。 您不需要为该级别的关系使用最短路径。
如果您希望寻找更大程度的关系,那么您应该查看邻接列表,但使用MySQL实现它并不容易。在该设置中需要注意一些问题:
仅举几例。