You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何优化按班级分组查询平均数量的SQL查询语句?

优化班级平均数量查询的方案

嘿,这个场景我太熟悉了!你原来用WHERE IN子查询的方式虽然能得到结果,但当两张表的数据量变大时,性能很容易掉链子——尤其是子查询返回的id列表很长的时候,数据库得反复做匹配查找,效率很低。咱们换个思路,用**表关联(JOIN)**来重构查询,不仅逻辑更清晰,执行效率也会高很多。

先还原你原来的查询逻辑(大概是这样)

你之前的写法可能类似下面这样,先按班级分组获取对应的id列表,再嵌套子查询计算平均值:

SELECT 
  t1.班级,
  (SELECT AVG(t2.数量) FROM TABLE2 t2 WHERE t2.table1_id IN (SELECT id FROM TABLE1 WHERE 班级 = t1.班级)) AS 平均数量
FROM TABLE1 t1
GROUP BY t1.班级;

优化后的查询语句

直接通过JOIN关联两张表,然后按班级分组计算平均值,一步到位:

SELECT 
  t1.班级,
  AVG(t2.数量) AS 平均数量
FROM TABLE1 t1
JOIN TABLE2 t2 ON t1.id = t2.table1_id
GROUP BY t1.班级;

为什么这个方案更优?

  • 避免了嵌套子查询的多次执行:数据库可以一次性完成表关联和分组计算,执行计划更高效,不会反复对子查询求值。
  • 更容易利用索引加速:关联操作依赖于两张表的关联字段,合理建索引能大幅提升查询速度。

进阶优化:添加合适的索引

如果数据量较大,给这两个字段建索引会让查询速度再上一个台阶:

  1. TABLE2覆盖索引(查询时无需回表取数据):
CREATE INDEX idx_table2_table1_id_quantity ON TABLE2(table1_id, 数量);
  1. TABLE1建联合索引(分组和关联时更快定位数据):
CREATE INDEX idx_table1_class_id ON TABLE1(班级, id);

特殊场景处理:保留无对应记录的班级

如果有些班级在TABLE1里存在,但TABLE2没有对应的数量记录,上面的JOIN会过滤掉这些班级。如果需要保留它们并显示平均数量为0,可以用LEFT JOIN配合COALESCE

SELECT 
  t1.班级,
  COALESCE(AVG(t2.数量), 0) AS 平均数量
FROM TABLE1 t1
LEFT JOIN TABLE2 t2 ON t1.id = t2.table1_id
GROUP BY t1.班级;

内容的提问来源于stack exchange,提问作者Jens

火山引擎 最新活动