内连接查询结果数量多于单表查询的原因分析及查询语句优化建议咨询
这事儿我太熟了!你遇到的情况核心原因是内连接时的重复匹配导致计数被放大,咱们来理清楚:
为什么内连接计数更高?
你的单表查询SELECT COUNT(myTable.name) from sch2.sample_detail as myTable where myTable.name IS NOT NULL;统计的是myTable里每条非空name的记录数——每条记录只算一次,所以结果是2864654。
但内连接查询中,如果sch1.otherTable里同一个name对应多条is_valid=1的记录,那么myTable里的一条记录会和otherTable中所有匹配的记录逐一连接,最终的结果集里会出现多条重复的myTable.name。COUNT(myTable.name)会把这些重复的条目全部算进去,自然总数就比单表查询还大了。
你可以跑这条SQL验证一下这个猜想:
SELECT name, COUNT(*) FROM sch1.otherTable WHERE is_valid=1 GROUP BY name HAVING COUNT(*) > 1;
如果返回结果,就说明确实存在重复的name条目在otherTable里。
如何修改查询语句?
如果你的需求是统计**myTable中存在匹配otherTable(且is_valid=1)的非空name的数量**,有两种靠谱的修改方式:
方式1:使用DISTINCT去重计数
在COUNT里加上DISTINCT,确保每个name只被统计一次:
SELECT COUNT(DISTINCT myTable.name) FROM sch2.sample_detail as myTable INNER JOIN sch1.otherTable as otherTable ON myTable.name = otherTable.name WHERE otherTable.is_valid = 1 AND myTable.name IS NOT NULL;
方式2:使用EXISTS子查询(推荐,性能更优)
EXISTS只会检查是否存在匹配的记录,不会生成重复的结果行,计数更准确,尤其是当otherTable的name和is_valid字段有索引时,性能会更好:
SELECT COUNT(myTable.name) FROM sch2.sample_detail as myTable WHERE myTable.name IS NOT NULL AND EXISTS ( SELECT 1 FROM sch1.otherTable as otherTable WHERE otherTable.name = myTable.name AND otherTable.is_valid = 1 );
这两种修改后的查询结果都会和你预期的一致——要么等于单表查询结果(如果所有非空name都在otherTable里有匹配),要么比单表查询结果少(因为过滤掉了otherTable里没有匹配的name)。
内容的提问来源于stack exchange,提问作者Fllappy

