一对多关联表SQL优化:重复使用approve列的优化方案咨询
优化多次子查询的点赞统计SQL
嘿,这个问题提得很到位!你的原始SQL确实存在性能优化空间——三次独立的子查询意味着每次查询a16s的一条记录时,都要对a16s_like表做一次扫描,当数据量上去之后,重复扫描的开销会越来越明显。
咱们可以用LEFT JOIN + 条件聚合的方式来重构查询,只需要扫描一次a16s_like表就能完成所有统计,效率提升不少:
SELECT A.id, A.pic, COUNT(B.p_id) AS Ashow, -- 统计总互动数 COUNT(IF(B.approve = '0', 1, NULL)) AS Nshow, -- 统计approve=0的数量 COUNT(IF(B.approve = '1', 1, NULL)) AS Yshow -- 统计approve=1的数量 FROM a16s A LEFT JOIN a16s_like B ON B.p_id = A.id GROUP BY A.id, A.pic ORDER BY A.id DESC;
如果你的数据库更适配CASE表达式(比如部分SQL方言对IF支持有限),也可以写成这种等价形式:
SELECT A.id, A.pic, COUNT(B.p_id) AS Ashow, SUM(CASE WHEN B.approve = '0' THEN 1 ELSE 0 END) AS Nshow, SUM(CASE WHEN B.approve = '1' THEN 1 ELSE 0 END) AS Yshow FROM a16s A LEFT JOIN a16s_like B ON B.p_id = A.id GROUP BY A.id, A.pic ORDER BY A.id DESC;
为什么这个方案更优?
- 减少表扫描次数:原始查询每条
a16s记录触发3次子查询,优化后只需要对a16s_like做一次关联扫描,大大降低IO开销。 - 逻辑更清晰:把所有统计逻辑集中在一个聚合查询里,可读性更强,也更容易维护。
- 兼容性好:两种写法都能在主流关系型数据库(MySQL、PostgreSQL等)中正常运行。
结果验证
拿你给出的测试数据举例:
- 对于
a16s.id=1,Ashow会返回5(总共有5条关联记录),Nshow返回2(approve=0的两条),Yshow返回3(approve=1的三条),和原始查询的结果完全一致。
内容的提问来源于stack exchange,提问作者robspin
相关产品推荐
相关产品推荐

