数据库查询比在一台服务器上查找LinkedIn类型第二级连接的算法更快吗?

时间:2012-09-15 18:21:33

标签: mysql algorithm graph graph-theory graph-algorithm

我在一个mysql服务器上有一个朋友id, u1, u2和约< 500,000条目的表格

我想拍摄userAuserB并检查他们是否有共同的朋友。

做得更快

select u2 from friends where u1 = userA and u2 IN (select u2 from friends where u1 = userB)

在图表上(在一台服务器上)运行最短路径算法?

标准方式是什么,像LinkedIn和Facebook这样的大型网络用来处理这个问题?

谢谢!

4 个答案:

答案 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实现它并不容易。在该设置中需要注意一些问题:

  • 不相交的图(可以通过维护子图上的传递闭包来处理,并在需要时合并它们),
  • 直接与无向图,
  • 数据分发(另一个答案提到hadoop作为加速处理的一种方式,但它需要一个好的分区方案)

仅举几例。