我经常遇到这样的数据库查询:
获取userX的所有条目(例如评论)以及userX的朋友的所有条目
这是在SQL(MySQL)中执行此操作的最佳方法,假设userX不是他自己的朋友。
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。其他方案?有条件的加入或某事......
答案 0 :(得分:0)
为什么不:
SELECT c.*
FROM comments
WHERE user = X OR user IN (
SELECT user2 FROM relation WHERE user1 = X
)
如果这很慢,你应该看一下执行计划。您可能缺少索引。
答案 1 :(得分: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
答案 2 :(得分:0)
你的#2没有任何问题。您很可能没有所需的索引。
作为一个学术案例研究,以下是应该返回相同结果集的各种表单。你应该用EXPLAIN
尝试每一个,并看看哪个最适合你(确保正确的索引在那里)(我偏向第三个,因为我发现它表现得一样好,如果不是更好它和它允许多个字段相关。您可以搜索SO或Google以获取有关IN
vs EXISTS
的MySQL性能的文章
UNION结果 - 这是你的#1的改进版本;数据在MySQL中仍然是UNIONed,而不是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)
<强> EXISTS 强>
一般来说,我更喜欢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)