查找连接(朋友的朋友,朋友的朋友)太慢的查询

时间:2014-04-19 04:49:37

标签: mysql sql

如果两个用户是朋友,我在"朋友"中有一个条目。这样的表就像这样:

   table: friends
   ------------------------
   uid1           uid2
   332            333

现在让我们说一个新用户(uid = 100)加入。我的应用程序找到她附近的用户,然后尝试向她显示他们的连接(朋友,朋友的朋友等)。我为此目的使用此查询:

           SELECT (fr.id IS NOT NULL)+(f2.id IS NOT NULL)*2+(fr.id IS NULL AND f2.id IS NULL)*3 AS connection
           FROM users u
           LEFT JOIN friends AS fr ON ((fr.uid1='100' AND fr.uid2=u.uid) OR (fr.uid1=u.uid AND fr.uid2='100'))
           LEFT JOIN (friends AS f1, friends AS f2) ON fr.id IS NULL AND
           (
            (f1.uid1='100' AND f1.uid2=f2.uid1 AND f2.uid2=u.uid) OR
            (f1.uid2='100' AND f1.uid1=f2.uid1 AND f2.uid2=u.uid) OR
            (f1.uid2='100' AND f1.uid1=f2.uid2 AND f2.uid1=u.uid) OR
            (f1.uid1='100' AND f1.uid2=f2.uid2 AND f2.uid1=u.uid)
           ) 
           WHERE [location near her] 

此查询将查找新用户附近的人,并为每个人找到" connection"的值。如果有新用户的朋友,则为1;如果他们有共同的朋友,则为2;否则为3。

查询过去工作正常,但现在我只有一点点用户(10,000)它变得非常慢(需要10秒才能找到新用户附近只有10个人的连接类型)。 我的查询或数据库方案中是否存在完全错误的问题?我知道定义索引会使事情变得更快,但我认为这样简单的查询需要10秒才能完成。我很感激任何建议。

1 个答案:

答案 0 :(得分:0)

我在sqlfiddle上工作以坚持你的问题。 这就是我的建议:

  • 请勿在{{1​​}}中使用OR条件,它是性能杀手,最好是使用left join
  • 进行2次加入或更多次加入
  • 请勿在第二个OR(效果杀手)中使用fr.id IS NULL,而是在选择部分使用left join
  • 使用(fr.id IS NOT NULL)+(fr.id IS NULL AND f2.id IS NOT NULL)*2显示1/2/3类型的连接(更易读)

以下是我建议的代码(例如:uid = 1的新用户):

CASE WHEN [cond] THEN [type_connection] ELSE 3 END

Here is the sqlfiddle demo used

希望有所帮助:)