MySQL优化sql连接查询

时间:2014-04-13 21:50:12

标签: mysql sql query-performance

我在接受采访时被问到要在白板上做什么,而我的解决方案对于白板的答案来说似乎太复杂了。

我有两个表,一个有id和名称作为表Person,另一个有id,person_id和friend_id作为表朋友。朋友表中的一行表示两个人之间的友谊。我想为" Gina"找到友谊的所有实例。不知道她的身份。

我想出了:

SELECT DISTINCT name FROM
(SELECT name1 AS name FROM
    (SELECT p1.name AS name1, p2.name AS name2 FROM friend f INNER JOIN person p1 ON f.person_id = p1.id INNER JOIN person p2 ON f.friend_id = p2.id WHERE p2.name LIKE 'Gina' OR p1.name LIKE 'Gina') AS group1
UNION ALL
SELECT name2 AS name FROM
    (SELECT p1.name AS name1, p2.name AS name2 FROM friend f INNER JOIN person p1 ON f.person_id = p1.id INNER JOIN person p2 ON f.friend_id = p2.id WHERE p2.name LIKE 'Gina' OR p1.name LIKE 'Gina') AS group2)
AS combo WHERE name <> 'Gina';

我在白板上思考不好,这不是最佳解决方案。任何人都可以优化这个吗?

为几个朋友制作了一个方便的东西,以后随处可见:

http://sqlfiddle.com/#!2/9d10b/16

2 个答案:

答案 0 :(得分:0)

如果你想要的是将吉娜列为朋友的人的名字,那就可以了。

SELECT person.name
  FROM person
  JOIN friend on friend.person_id = person.id
 WHERE friend.friend_id = (SELECT id FROM person WHERE name = 'Gina')
;

虽然只有三个人,但你无法真正测试对手。更好的测试是添加一个不应该出现在结果集中的第四个人。

<强>更新

鉴于您的更新架构,这将获得Gina的朋友和Gina作为朋友的人。 It runs at least as fast or slightly faster比你的{{3}}。根据我的经验,十分之九,尽可能简单地说明查询并让数据库弄清楚是最好的方法。

SELECT person.name
  FROM friend
  JOIN person ON person.id = friend.person_id
 WHERE friend.friend_id = (SELECT id FROM person WHERE name = 'Gina')
UNION
SELECT person.name
  FROM friend
  JOIN person ON person.id = friend.friend_id
 WHERE friend.person_id = (SELECT id FROM person WHERE name = 'Gina')
;

答案 1 :(得分:0)

这有效,但我不确定哪一个更快......你必须进行基准测试......

SET @gina_id=(SELECT id FROM person WHERE name = 'Gina');
SELECT DISTINCT person.name
FROM person
JOIN friend on (friend.person_id = person.id or friend.friend_id=person.id)
WHERE (friend.friend_id = @gina_id
OR friend.person_id = @gina_id)
AND person.id != @gina_id

这里是小提琴:http://sqlfiddle.com/#!2/962db/3