如果两个用户是朋友,我在"朋友"中有一个条目。这样的表就像这样:
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秒才能完成。我很感激任何建议。
答案 0 :(得分:0)
我在sqlfiddle上工作以坚持你的问题。 这就是我的建议:
OR
条件,它是性能杀手,最好是使用left join
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
希望有所帮助:)