MySQL中SELECT *与GROUP BY JSON查询性能差异疑问
MySQL查询性能差异解析
第二条查询的执行逻辑
把SELECT COUNT(*) FROM table GROUP BY JSON_EXTRACT(info, "$.id");的执行过程拆解开看:
- 定向读取数据:MySQL只会扫描表中的
info列,不需要加载其他列的内容。 - 解析JSON字段:对每一行的
info列执行JSON_EXTRACT操作,提取出JSON结构里的$.id值。 - 分组统计计数:以提取出的
id作为分组依据,统计每个分组对应的行数,最终仅返回分组的id值和对应的计数结果。
为什么第一条查询反而更慢?
你原本觉得第二条应该更慢,是默认认为JSON解析+分组会带来额外开销,但实际结果相反,核心原因在这几点:
- 数据读取量差距极大:
SELECT *需要读取表中所有列的数据,如果表包含大字段(比如长文本、Blob,或是结构复杂的大JSON),磁盘IO和内存占用会大幅飙升,这部分开销远超过JSON解析和分组的消耗。- 第二条查询只需要读取
info单列,数据量小很多,磁盘读写的压力直接降低。
- 结果集大小天差地别:
SELECT *会返回全表所有行的所有列,结果集可能非常庞大,从数据库传输到客户端需要额外时间,客户端接收和处理这些数据也会消耗资源。- 第二条查询的结果是分组后的统计值,行数远少于原表(哪怕每个
$.id都是唯一的,结果也只有id和计数两列,数据量仍远小于全表)。
- MySQL的执行路径优化:
- 分组计数这类查询,MySQL会采用更高效的执行逻辑,哪怕没有索引,单列扫描的效率也远高于全列扫描。而且分组计数只需要维护每个分组的计数状态,无需保存全量行数据,内存占用更低。
验证建议
要进一步确认的话,可以做这两个小测试:
- 执行
SELECT info FROMtable``,对比它和SELECT *的速度,就能直观看出全列读取的开销影响。 - 查看表结构,确认是否存在大字段或较多列,这些都会放大
SELECT *的执行开销。
内容的提问来源于stack exchange,提问作者Tuấn Kiệt
相关产品推荐
相关产品推荐

