MySQL:筛选无任何Score≥7记录的唯一Name列表
针对Person大表的查询解决方案
刚好之前处理过类似的大表查询需求,针对你要找没有任何Score≥7记录的唯一Name这个场景,我整理了几个既正确又兼顾性能的方案,你可以根据实际情况选择:
方法1:NOT EXISTS(大表首选,性能友好)
这个思路最直观——直接找那些不存在任何Score≥7记录的Name:
SELECT DISTINCT p.Name FROM Person p WHERE NOT EXISTS ( SELECT 1 FROM Person p2 WHERE p2.Name = p.Name AND p2.Score >= 7 );
如果你的表上建立了(Name, Score)的复合索引,这个查询会跑得非常快:子查询可以通过索引快速定位每个Name是否存在符合条件的记录,完全不用全表扫描。
方法2:LEFT JOIN + IS NULL
这是和NOT EXISTS等价的写法,通过左连接匹配有Score≥7的Name,再筛选出匹配失败的结果:
SELECT DISTINCT p.Name FROM Person p LEFT JOIN Person p2 ON p.Name = p2.Name AND p2.Score >= 7 WHERE p2.Name IS NULL;
同样,(Name, Score)的复合索引能极大提升这个查询的性能,原理和NOT EXISTS一致。
方法3:GROUP BY + HAVING(适合需要聚合信息的场景)
如果你还想顺便确认每个Name的最高Score,这种方法很合适:
SELECT Name FROM Person GROUP BY Name HAVING MAX(Score) < 7;
它会按Name分组,筛选出分组内最高Score小于7的Name,结果天然是唯一的,不用额外加DISTINCT。不过如果表特别大,GROUP BY的开销可能比前两种略高,但有合适的索引(比如Name单索引或(Name, Score)复合索引)的话,性能也不会差。
关键性能提示
因为你的表有900万行,一定要记得建立合适的索引:
- 优先创建
(Name, Score)的复合索引,上面三种查询都能用到它 - 避免全表扫描,否则查询会慢到难以接受
内容的提问来源于stack exchange,提问作者File
相关产品推荐
相关产品推荐

