1

我经常遇到这样的数据库查询:

获取 userX 的所有条目(例如评论)以及 userX 的朋友的所有条目

假设 userX 不是他自己的朋友,这是在 SQL (MySQL) 中执行此操作的最佳方法。

1. 做两个查询,稍后用 PHP 合并它们

a = SELECT *
    FROM comments
    WHERE user = X
b = SELECT c.*
    FROM comments c
    INNER JOIN relation r ON r.user2 = c.user
    WHERE r.user1 = X
merge(a, b)

这就是我通常所做的。它相当高效,但我不能将事物用作 ORDER BY 或 LIMIT

2. 带有 IN 和 UNION 的子查询

SELECT c.*
FROM comments
WHERE user IN (
    SELECT "X"
    UNION
    SELECT user2 FROM relation WHERE user1 = X
)

这似乎很慢,因此是个坏主意,不是吗?

3. 其他解决方案?条件连接什么的...

4

3 回答 3

0

为什么不:

SELECT c.*
FROM comments
WHERE user = X OR user IN (
    SELECT user2 FROM relation WHERE user1 = X
)

如果这很慢,您应该查看执行计划。您可能缺少索引。

于 2013-11-07T13:28:24.153 回答
0

一种方法是从用户表开始查询。将它与关系表连接起来。然后,您可以使用有条件的“ON”语句加入对此的评论。这样 MySQL 可以使用索引。

select c.* from users a
left outer join relation friend on a.id = friend.user1_id
join comments c on (c.user_id = a.id or c.user_id = friend.user2_id)
where a.id = 1
group by c.id;

这是一个工作示例:http ://sqlfiddle.com/#!2/da298/1

于 2013-11-07T13:47:44.977 回答
0

您的#2 没有任何问题。您很可能没有所需的索引。

作为一个学术案例研究,这里有各种应该返回相同结果集的形式。你应该尝试每一个,EXPLAIN看看哪个对你表现最好(确保那里有正确的索引)(我偏爱第三个,因为我发现它的性能即使不是更好也一样好,并且它允许多个字段是相关的。你可以搜索 SO 或 Google 以获取有关INvs的 MySQL 性能的文章EXISTS

UNION 结果 - 这是您的 #1 的改进版本;数据仍然在 MySQL 中联合,而不是 PHP

SELECT *
FROM comments
WHERE user = X
UNION
SELECT c.*
FROM comments c
INNER JOIN relation r 
  ON r.user2 = c.user
WHERE r.user1 = X

你的选择#2 -IN

SELECT c.*
FROM comments
WHERE user IN (
    SELECT "X"
    UNION
    SELECT user2 FROM relation WHERE user1 = X) 

存在

一般来说,我更喜欢这个,IN因为它允许关联多个字段

SELECT c.*
FROM comments AS c
WHERE c.user = X
   OR EXISTS(SELECT *
             FROM relation AS r
             WHERE r.user1 = X
                AND r.user2 = c.user)
于 2013-11-07T13:53:10.623 回答