SQL优化多个连接结果中的重复记录

时间:2013-03-25 19:51:29

标签: mysql sql database join duplicates

例如,我有3个表: 首先像'用户',每个用户都存储他的名字。第二个 - “位置”,用户存储的地址 - 通常为1个用户的1个地址。第三 - “消息” - 每个用户通常都有一堆记录。

加入这三个表时 - 比如

SELECT Users.name, Location.address, Messages.message FROM Users
LEFT JOIN Location ON Location.user_id = Users.id
LEFT JOIN Messages ON Messages.user_id = Users.id
WHERE blah blah

结果将包含许多重复记录,因为表'Messages'为每个用户提供了许多记录。而这些重复项将减慢提取速度。 所以我正在寻找解决方案,如何优化它。 例如,我使用GROUP_CONCAT()尝试GROUP BY User.id - 但当GROUP_CONCAT()的结果相对较长时,GROUP_CONCAT()开始返回NULL。我无法掌握它,我试图将group_concat_max_lenmax_allowed_packet设置为高值 - 所有这些都没有运气。

那么,有人对此有任何想法吗?

PS 可能很重要的一点,在我的实际情况中,我不是只有一个列'消息',而是有很多列,还有很多不同的行。我的'Messages'表格看起来像'message','time','recipient',删除','medium'等,而我的GROUP_CONCAT()包含所有这些字段。

UPD: 如果只有一条记录显示为GROUP_CONCAT(),则NULL似乎会删除所有结果。 例如,如果使用GROUP_CONCAT(Messages.message, Messages.time),并且偶尔在一行中的时间将为NULL,则它将返回NULL。

3 个答案:

答案 0 :(得分:0)

在这种情况下,您实际上可能会受益于像Mongodb这样的文档存储数据库,用于存储消息。

答案 1 :(得分:0)

您可能需要group_concat(distinct)

SELECT Users.name, group_concat(distinct Location.address) as locations,
       group_concat(distinct Messages.message) as messages
FROM Users
LEFT JOIN Location ON Location.user_id = Users.id
LEFT JOIN Messages ON Messages.user_id = Users.id
WHERE blah blah
group by users.name

答案 2 :(得分:0)

  

结果将包含许多重复记录,因为表'Messages'为每个用户提供了许多记录。

通过“复制”,是否意味着每个唯一消息都会有一行,并且该行将包含其他行中存在的用户名和位置的值?您是否想要一种方法将所有消息刷成一个,以便每个用户+位置只有一行?对于速度 ??

如果这是一个表现问题,我很想知道如何衡量,以及什么是足够快。我也想知道,如果你成功了,你将如何区分信息。