【问题标题】:MySQL Most efficient way to get all rows with at least one associated rowMySQL 获取所有行至少有一个关联行的最有效方法
【发布时间】:2020-03-08 15:29:39
【问题描述】:

给定一个表 members 和一个表 devices,其中每个成员可以有 0 台设备,那么让所有成员至少拥有一个设备的最快方法是什么?

select m.*, md.* from members m
left join (
    SELECT count(*) as c, memberId from member_devices d GROUP BY d.memberId
) md ON m.memberId = md.memberId
WHERE md.c > 0

这可行,但似乎真的很慢。

select s.*  from members m where
EXISTS (
    SELECT 1 FROM member_devices md WHERE m.memberId = md.memberId
)

也可以,而且可能会快一点(?)

有人有经验吗?谢谢!

【问题讨论】:

    标签: mysql sql join subquery query-performance


    【解决方案1】:

    第二个选项使用EXISTS 和相关子查询,肯定是这里最快的选项。

    与其他选项不同,它不需要聚合和加入。聚合是一项昂贵的操作,通常不能很好地扩展(当要处理的记录数量增加时,性能往往会急剧下降)。

    此外,您实际上不需要计算每个组中有多少条记录。您只想知道是否至少有一条记录可用。这正是EXISTS 的用途。

    为了提高查询性能,请确保您具有以下索引(如果您正确实现了与外键的关系,它们可能已经存在):

    members(memberId)
    member_devices(memberId)
    

    【讨论】:

      【解决方案2】:

      “INNER JOIN”在两个表中都存在匹配时返回行。你可以这样做:

      SELECT m.*, md.*
      FROM members m
      INNER JOIN devices md ON m.memberId = md.memberId
      

      【讨论】:

      • 此查询为语法错误(未选择任何内容)。此外,这将为拥有多个设备的成员返回多条记录。
      • 是的,如果有多个设备,它将返回多个记录。如果他只想要成员列表,最好的方法是“存在”
      猜你喜欢
      • 1970-01-01
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-25
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多