MySQL内连接问题:如何高效筛选存在订单历史的人员
解决方案:筛选存在订单历史的人员记录
以下是几种高效的实现方式,可避免全表扫描带来的性能问题:
方法1:使用EXISTS子查询过滤(推荐)
通过EXISTS判断人员在任意一个订单表中存在记录,利用person_id索引快速匹配,无需关联全表:
SELECT * FROM persons p WHERE EXISTS ( SELECT 1 FROM orders o WHERE o.person_id = p.id ) OR EXISTS ( SELECT 1 FROM old_orders oo WHERE oo.person_id = p.id ) LIMIT 100;
如果需要同时返回订单详情,可在过滤后再关联两个表:
SELECT * FROM persons p LEFT JOIN orders o ON p.id = o.person_id LEFT JOIN old_orders oo ON p.id = oo.person_id WHERE EXISTS ( SELECT 1 FROM orders o WHERE o.person_id = p.id ) OR EXISTS ( SELECT 1 FROM old_orders oo WHERE oo.person_id = p.id ) LIMIT 100;
方法2:使用IN子查询+去重UNION
通过UNION合并两个表的唯一person_id,再匹配人员表,UNION会自动去重,减少匹配数据量:
SELECT * FROM persons p WHERE p.id IN ( SELECT person_id FROM orders UNION SELECT person_id FROM old_orders ) LIMIT 100;
同样,若需订单信息,后续添加LEFT JOIN即可。
方法3:WHERE过滤+DISTINCT去重
保留原关联逻辑,通过WHERE条件筛选出至少有一个订单的记录,再用DISTINCT避免重复行:
SELECT DISTINCT p.*, o.*, oo.* FROM persons p LEFT JOIN orders o ON p.id = o.person_id LEFT JOIN old_orders oo ON p.id = oo.person_id WHERE o.person_id IS NOT NULL OR oo.person_id IS NOT NULL LIMIT 100;
注意:这种方式在订单数据量大时,DISTINCT可能带来额外性能开销,优先选择前两种方法。
内容的提问来源于stack exchange,提问作者Anton Kim
相关产品推荐
相关产品推荐

