MySQL优化sql连接查询

Posted

技术标签:

【中文标题】MySQL优化sql连接查询【英文标题】:MySQL optimizing sql join query 【发布时间】:2014-04-13 21:50:11 【问题描述】:

我在一次采访中被要求在白板上做这个,我的解决方案似乎太复杂了,无法用白板回答。

我有两张表,一张有 ids 和 names 作为表 Person,另一个有 id、person_id 和friend_id 作为表 Friend。 Friend 表中的一行表示两个人之间的友谊。我想在不知道她身份的情况下找到“吉娜”的所有友谊实例。

我想出了:

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';

我在白板上的想法不是很好,这不是最好的解决方案。谁能优化一下?

为几个朋友制作了一个 sqlfiddle 以供之后捣乱:

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

【问题讨论】:

他们要求你做一个简单的JOIN声明。 不管被问到什么问题,有没有办法针对我的问题优化我的回答 @hermanthriller 你在这里找到答案了吗?还有什么我可以帮忙的吗? 【参考方案1】:

这可行,但我不确定哪个更快...您必须进行基准测试...

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

【讨论】:

【参考方案2】:

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

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 比你的。以我的经验,十分之九,尽可能简单地说明查询并让数据库弄清楚是最好的方法。

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')
;

【讨论】:

我添加了第四个名字和关系,你的工作更简单。 我感觉这可能也很快 嗯,它确实有效,当friend.person_id 是Gina 的id 时,它是如何工作的?这是因为 Fred 有 2 行,但是如果你删除了朋友表中的第 1 行,这将不再起作用 所以,我认为这个实际上有点错误。如果她出现在friend_id 列中,它只会找到gina 的朋友,但如果她出现在person_id 列中则不会。试试这个小提琴。 sqlfiddle.com/#!2/53cb6/2 @hermanthriller 是的,这个问题从来没有解释过互惠在这个模式中是如何工作的,所以它有点开放式

以上是关于MySQL优化sql连接查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL执行与优化

MySQL查询优化

针对标签上的多对多连接优化 MySQL 查询

在 3 个大表上使用内连接优化 SQL 查询

Mysql的SQL优化指北

分析MySQL执行的流程(连接缓存分析优化执行Undo LogBinlogRedo Log)