在前一篇我们分析了一个反直觉的 MySQL 查询案例,MySQL 查询性能: 越少的结果集越慢 越多的越快? 1/2 (https://ufqi.com/blog/mysql-limit-10-vs-100/ ),这一次我们继续进行另外一个 MySQL 查询的分析,无独有偶,这个看起来也很反直觉,两个对比的 SQL ,简单的看起来很慢,而复杂一些的 SQL 反而执行起来却是很快。
在 UfqiNews 有福新闻 中,运行日志中,偶尔很看到类似下面这样的警告信息。
mod/news: slow sql:select wordid, count(pageid) as pagecount from news_page2wordtbl where inserttime>=’2025-12-20 00:00:00′ group by wordid order by pagecount desc limit 18, return and wait…. func:[getTopXWord]…
针对这样的预警信息,优化起来却是无从下手,除了启用缓存、增加索引等常规手段外,再无良策,按照传统的思路,这个 SQL 查询已经很简单了,性能瓶颈在 group by 环节,可是业务逻辑就需要这样的数据。怎么办?
现在有了 人工智能 AI 助手,一切问题都难不倒它,所有人都应该大胆地去尝试各种不懂不会更不敢的东西。
AI 助手 宛如开了上帝视角一样,无所不能,无所不在。
下面就是通过 AI 助手 字节跳动的 豆包,针对这个 SQL 查询反直觉的解析与处理优化建议。
问题描述:
MYSQL 对比分析,两个查询意义相同,
mysql> select wordid, count(pageid) as pagecount from news_page2wordtbl where pageid in (select id from news_pagetbl where inserttime>=’2025-12-20′) and inserttime>=’2025-12-20 18:00:00′ group by wordid order by pagecount desc limit 18;
这个相对复杂查询会相对较快,几秒可以完成,
而下面这个简单的查询,却很慢,几十秒都无法返回预期结果集,
mysql> select wordid, count(pageid) as pagecount from news_page2wordtbl where inserttime>=’2025-12-20 18:00:00′ group by wordid order by pagecount desc limit 18;
看似更复杂的第一个 MySQL 查询,反而比第二个简单查询执行更快,我们来从数据过滤量级、索引生效、聚合排序开销三个核心维度拆解原因,并补充优化建议.
一、核心原因:第一个查询多了「前置数据过滤」,大幅减少后续处理量
两个查询的关键差异在于:第一个查询通过 pageid IN (子查询) 多增加了一层过滤条件,这不是 “复杂” 的负担,而是提前缩小了需要处理的数据集规模,这是它更快的根本原因。
- 两个查询的过滤逻辑对比
- 第二个查询(慢):仅依靠
news_page2wordtbl自身的inserttime>='2025-12-20 18:00:00'过滤,会取出这张表中该时间点之后的所有记录,无论这些pageid是否在news_pagetbl中有有效数据(即inserttime>='2025-12-20'的页面)。 - 第一个查询(快):是双重过滤的交集,先通过子查询从
news_pagetbl筛选出2025-12-20之后的有效pageid,再让news_page2wordtbl仅匹配这些有效pageid,同时满足自身的inserttime条件。
- 第二个查询(慢):仅依靠
- 关键结论:无效记录被提前排除
news_page2wordtbl中满足inserttime>='2025-12-20 18:00:00'的记录里,大概率包含大量「无效pageid」(即这些pageid对应的页面在news_pagetbl中早于2025-12-20,无业务意义)。第一个查询通过pageid IN (子查询)提前剔除了这些无效记录,使得后续的group by、count、order by只需要处理小批量有效数据;而第二个查询需要处理大批量包含无效数据的全量结果,两者的处理开销天差地别。
二、辅助原因:索引的生效效率差异
查询速度的快慢与索引是否高效生效直接相关,两个查询的索引利用效率存在明显差距:
- 子查询的索引支撑(低成本高效过滤)子查询
select id from news_pagetbl where inserttime>='2025-12-20'中,若news_pagetbl为inserttime建立了索引(推荐「覆盖索引」idx_inserttime_id (inserttime, id)),该子查询会:- 快速通过索引定位到
2025-12-20之后的记录,无需全表扫描; - 覆盖索引直接包含
id字段,无需回表读取全表数据,瞬间返回有效pageid列表,几乎无性能瓶颈。
- 快速通过索引定位到
news_page2wordtbl的索引利用差异- 第一个查询:过滤条件是
pageid IN (...) AND inserttime>='...',若news_page2wordtbl建立了联合索引(如idx_pageid_inserttime_wordid (pageid, inserttime, wordid)),索引会同时满足两个过滤条件,直接过滤出有效数据,且索引包含wordid,支撑后续group by无需额外排序。 - 第二个查询:仅靠
inserttime>='...'过滤,存在两个问题:① 若inserttime索引的选择性不高(即该时间后的数据占表总数据比例较大,比如超过 30%),MySQL 会认为索引扫描效率不如全表扫描,直接放弃索引,走全表扫描,开销暴增;② 即便inserttime索引生效,后续group by wordid仍需对大批量数据创建临时表、进行文件排序,消耗大量 CPU 和 IO 资源。
- 第一个查询:过滤条件是
三、额外原因:聚合与排序的开销差异
group by wordid 和 order by pagecount desc 是查询中开销较大的操作,其开销与处理的数据量正相关:
- 第一个查询:处理数据量小,
group by无需创建大规模临时表,order by仅需对少量聚合结果排序,甚至可利用索引避免文件排序,开销极低; - 第二个查询:处理数据量大,
group by需创建大容量临时表存储聚合结果,order by需对大量聚合结果进行文件排序(磁盘 IO 操作),这两个操作是查询变慢的 “重灾区”。
四、补充:验证方法与优化建议
- 验证数据量级差异(佐证核心原因)执行以下两条语句,对比返回的记录数,即可直观看到数据量差距:
-- 子查询返回的有效pageid数量(大概率较少)select count(distinct id) from news_pagetbl where inserttime>='2025-12-20';-- 第二个查询需要处理的记录数(大概率较多)select count(pageid) from news_page2wordtbl where inserttime>='2025-12-20 18:00:00'; - 索引优化(进一步提升效率)
news_pagetbl:创建覆盖索引idx_inserttime_id (inserttime, id),子查询无需回表,直接从索引获取数据;news_page2wordtbl:创建联合索引idx_pageid_inserttime_wordid (pageid, inserttime, wordid),实现 “过滤 – 聚合 – 计数” 全流程覆盖索引扫描,无需读取表数据。
- SQL 改写(子查询→JOIN,优化大结果集场景)当子查询返回的
pageid较多时,IN可能不如INNER JOIN高效,等价改写如下:select np2w.wordid, count(np2w.pageid) as pagecount from news_page2wordtbl np2winner join news_pagetbl np on np2w.pageid = np.idwhere np.inserttime >= '2025-12-20' and np2w.inserttime >= '2025-12-20 18:00:00'group by np2w.wordidorder by pagecount desc limit 18;
总结
- 第一个查询更快的核心是「
pageid IN (子查询)前置过滤」,大幅减少了后续聚合、排序的处理数据量; - 索引的高效生效是辅助,避免了全表扫描和额外回表开销;
- 看似 “复杂” 的查询不一定慢,关键在于是否能有效缩小数据处理规模,这是 MySQL 查询优化的核心思路之一。

有福新闻 UfqiNews
这里呈现热点全局, 尺寸间一览所有令人关注的疑点焦点;
这里表达条分缕析, 视野内一睹各个脉络清晰的故事主线.
有福新闻UfqiNews 带来全新的资讯阅览体验, 不信息过载, 亦不信息茧房.
在寻求最大社会共识和满足千人千面之间谋取平衡,
在满足广泛涉猎与追求术业专攻之间谋取平衡.
媒介插上人工智能的翅膀将如虎添翼, 与资讯比翼双飞.
新闻爱好者的良心之选, 匠心之作.
UfqiNews presents the hot spots globally, with all interesting points at a glance.
Information is organized here and there is a clear storyline within every single detail.
UfqiNews brings a brand new reading experience, no information overload and no information Cocoons,
In seeking a balance of the maximum social consensus and meeting thousands of people for each interest,
In achieving a balance between satisfying a wide range of hunting and pursuing specialization in the industry.
That media is being born with wings of the artificial intelligence will be even more powerful and the information will fly swifter than ever.
Better choices of newsreaders and the art of work from them.








