【发布时间】:2011-10-18 12:31:09
【问题描述】:
我想在我的网站上创建会员墙(facebook 风格)。 基于:
- 会员好友的最后一集。
- 会员朋友的最后档案。
- 成员文件的最后一个 cmets。
表结构:
friendship
userid | friendid | status
---------------------------------
user_table
userid | username
---------------------------------
files_table
file_id | file_title | file_desc | dl_date
---------------------------------
comments_table
comid | userid | file_id | com_date
这是我的 mysql 查询,它有效。但我想知道你的想法,让它变得更好。
--Last files of member's friends
-- Find files of friendship.friendid=$userid
SELECT files_table.file_id AS c1, files_table.file_title AS c2, files_table.file_desc AS c3, files_table.dlauthor AS c4, files_table.dl_date AS date, IF(files_table.file_id IS NOT NULL, 'Friends_eBooks',FALSE) as Type
FROM friendship
LEFT JOIN user_table ON friendship.userid = user_table.userid
LEFT JOIN files_table ON files_table.dlauthor = user_table.username
WHERE friendship.friendid = $userid
AND friendship.STATUS = '1'
-- Find files of friendship.userid=$userid
UNION
SELECT files_table.file_id AS c1, files_table.file_title AS c2, files_table.file_desc AS c3, files_table.dlauthor AS c4, files_table.dl_date AS date, IF(files_table.file_id IS NOT NULL, 'Friends_eBooks',FALSE) as Type
FROM friendship
LEFT JOIN user_table ON friendship.userid = user_table.userid
LEFT JOIN files_table ON files_table.dlauthor = user_table.username
WHERE friendship.userid = $userid
AND friendship.STATUS = '1'
UNION ALL
-- Last comments of member's friends
-- Find comments of friendship.friendid=$userid
SELECT comments_table.comid AS c1, user_table.username AS c2, comments_table.dl_comment AS c3, comments_table.file_id AS c4, comments_table.com_date AS date, IF(comments_table.comid IS NOT NULL, 'Friends_Comments', FALSE) as Type
FROM friendship
LEFT JOIN user_table ON friendship.userid = user_table.userid
LEFT JOIN comments_table ON user_table.userid = comments_table.userid
WHERE friendship.friendid = $userid
AND friendship.STATUS = '1'
UNION
-- Find comments of friendship.userid=$userid
SELECT comments_table.comid AS c1, user_table.username AS c2, comments_table.dl_comment AS c3, comments_table.file_id AS c4, comments_table.com_date AS date, IF(comments_table.comid IS NOT NULL, 'Friends_Comments', FALSE) as Type
FROM friendship
LEFT JOIN user_table ON friendship.friendid = user_table.userid
LEFT JOIN comments_table ON user_table.userid = comments_table.userid
WHERE friendship.userid = $userid
AND friendship.STATUS = '1'
-- Last comments on member's files
UNION ALL
SELECT comments_table.comid AS c1,user_table.username AS c2,comments_table.dl_comment AS c3, files_table.file_id AS c4,comments_table.com_date AS date, IF(comments_table.comid IS NOT NULL, 'My_Comments', FALSE) as Type
FROM files_table
LEFT JOIN comments_table ON files_table.file_id = comments_table.file_id
LEFT JOIN user_table ON comments_table.userid = user_table.userid
WHERE
(files_table.status=1) AND
(files_table.dlauthor=$userid)
ORDER by date DESC
解释:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY friendship ref friendid friendid 3 const 22 Using where
1 PRIMARY user_table eq_ref PRIMARY PRIMARY 4 ketabnak_ebooks.friendship.userid 1
1 PRIMARY files_table ref dlauthor dlauthor 92 func 10
2 UNION friendship ref PRIMARY PRIMARY 3 const 11 Using where
2 UNION user_table const PRIMARY PRIMARY 4 const 1
2 UNION files_table ref dlauthor dlauthor 92 func 10
3 UNION friendship ref friendid friendid 3 const 22 Using where
3 UNION user_table eq_ref PRIMARY PRIMARY 4 ketabnak_ebooks.friendship.userid 1
3 UNION comments_table ref userid userid 3 ketabnak_ebooks.user_table.userid 6
4 UNION friendship ref PRIMARY PRIMARY 3 const 11 Using where
4 UNION user_table eq_ref PRIMARY PRIMARY 4 ketabnak_ebooks.friendship.friendid 1
4 UNION comments_table ref userid userid 3 ketabnak_ebooks.user_table.userid 6
5 UNION files_table ref dlauthor dlauthor 92 const 294 Using where
5 UNION comments_table ref file_id file_id 3 ketabnak_ebooks.files_table.file_id 11
5 UNION user_table eq_ref PRIMARY PRIMARY 4 ketabnak_ebooks.comments_table.userid 1
NULL UNION RESULT <union1,2,3,4,5> ALL NULL NULL NULL NULL NULL Using filesort
弱点:
查询花费了很多时间。
所有表的列数应该相等。
我已经使用Friendship 表找到所有会员的朋友。
Status当会员的好友被接受好友请求时为1。
首先,Userid = Memberid:
Userid | Friendid | Status
1 | 4 | 0
1 | 8 | 1
1 | 9 | 1
然后,我使用 UNION 来合并 where Friendid = Memberid:
Userid | Friendid | Status
2 | 1 | 0
3 | 1 | 0
5 | 1 | 1
【问题讨论】:
-
能否请您发布您联合的每个查询的执行计划?我想
friendship表比其他表要少得多,在这种情况下,最好先过滤掉这个表,然后将它与查询中的其余表连接起来 -
如你所见,我不擅长 MySQL。我的查询可以正常工作,但我很确定它会好得多。我不知道如何使用
Friendship表作为过滤器。你能帮忙吗? -
要添加计划,请执行“explain put_your_query_here”并将其添加到您的帖子中。请尝试以下查询 link 并将其与您在 union 中的第一个查询进行比较。
-
解释我的查询:pastebin.com/BFz2G1dU 解释你的查询:pastebin.com/4qw89bEZ
-
计划似乎没问题。请确保您在
friendship.friendid上有索引。这就是我能帮助你的全部。我想还有另一种改进方法(但我可以帮助或不能......这取决于......):您可以重写您的查询并从联合中的每个查询中选择user_table并将此表与结果集连接起来。这就是我所能建议的。
标签: mysql sql facebook union facebook-wall