【问题标题】:SQL optimizing duplicate records in multiple join resultsSQL优化多个连接结果中的重复记录
【发布时间】:2013-03-15 10:43:42
【问题描述】:

例如,我有 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

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

嗯,有人对此有什么想法吗?

ps 可能需要注意的是,在我的实际情况中,我有很多列,而不是只有一列“消息”,并且有许多不同的行。我的“消息”表看起来像“消息”、“时间”、“收件人”、“已删除”、“中”等,我的 GROUP_CONCAT() 包含所有这些字段。

更新: 如果只有一条记录似乎是NULL,则似乎GROUP_CONCAT() 会丢弃所有结果。 例如如果使用GROUP_CONCAT(Messages.message, Messages.time),并且偶尔一行时间为NULL,则返回NULL。

【问题讨论】:

    标签: mysql sql database join duplicates


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      你可能想要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
      

      【讨论】:

        【解决方案3】:

        结果将包含许多重复记录,因为表“消息”对于每个用户都有许多记录。

        “重复”是否意味着对于每个 唯一 消息将有一行,并且该行将包含其他行中存在的用户名和位置值?您是否在寻求一种将所有消息合并为一个的方法,以便每个用户+位置只有一行? 速度??

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

        【讨论】:

        • 你的理解是对的。是的 - 为了速度,因为获取等于用户数量的行数比获取所有消息数量长度(10 倍,100 倍以上)和重复记录的数据要快得多。
        • 正如我所说,我很想知道你是如何得出这个结论的。除非您已经对其进行了测试,否则您的工作只是基于一个简单的假设,而不是设计的良好基础。如果您已经对其进行了测试,我很想看看这些数字,以及您将如何区分合并的消息。如果您还没有对其进行测试,那么您就是在一个简单的假设上增加了设计的复杂性,这几乎就是过早优化的定义。
        • 我已经对其进行了测试,并且连接技术显示出优于简单连接的优势。好像你有强烈的反对意见,你怎么能支持它?连接是相当便宜的操作。我以这种方式进行了拆分:我不仅将消息连接起来,而且将具有行 ID 的消息与消息和消息本身连接起来,并用分隔符将它们分隔开。而且我确实有另一列,其中仅连接了消息 rowID。并且以这种方式连接了有关消息的其他数据 - 日期时间和其他,并且通过这种技术,我能够轻松解决丢失数据的问题。
        • 我现在无法提供数字,因为它都丢失了,但也许值得创建一个单独的主题,对这项技术进行共同的分析和讨论。可能会很有趣。
        猜你喜欢
        • 2018-02-24
        • 1970-01-01
        • 2013-04-22
        • 2018-10-30
        • 1970-01-01
        • 1970-01-01
        • 2018-09-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多