You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加条件后SQL查询从262ms骤增至28s,原因何在?

为何添加AND p.site_id = 3后SQL查询耗时剧增?

原始查询语句

SELECT
DATE(ar.created_at) AS my_date,
COUNT(*) AS requests,
SUM(ar.is_scrubbed) AS scrubbed_requests,
SUM(ar.has_state_mismatch) AS state_mismatch_total,
AVG(ar.special_result) AS special_avg
FROM advert_requests ar
LEFT JOIN placements p ON p.id = ar.placement_id
WHERE ar.created_at >= '2022-11-22' AND ar.created_at < '2022-11-25'
-- 为何添加该条件后耗时剧增?
AND p.site_id = 3
AND ar.debug = 0
GROUP BY my_date
ORDER BY my_date DESC;

查询耗时对比

  • 移除AND p.site_id = 3条件时:查询耗时约200-300ms,对应的执行计划截图:
    移除p.site_id条件时的执行计划
  • 添加AND p.site_id = 3条件后:查询耗时在4秒至28秒之间,对应的执行计划截图:
    添加p.site_id条件时的执行计划

原因分析

  1. LEFT JOIN 逻辑转为 INNER JOIN
    原本的LEFT JOIN会保留advert_requests中所有符合条件的行,哪怕没有匹配的placements记录。但添加p.site_id = 3后,WHERE子句中对p表的非NULL约束会自动将查询转为INNER JOIN——只有同时匹配advert_requests行和placements中site_id=3行的记录才会被保留,彻底改变了查询的执行逻辑。

  2. 执行计划的效率差异

    • 移除p.site_id条件时:优化器可以利用advert_requests表上的created_at+debug联合索引,快速筛选出时间范围内且debug=0的行。由于查询不需要用到placements表的任何字段,优化器甚至会直接跳过JOIN操作,直接对过滤后的行进行聚合,这是耗时极短的核心原因。
    • 添加p.site_id条件后:优化器必须先处理placements表的筛选和关联逻辑。如果placements表的site_id字段没有建立索引,会导致全表扫描;如果advert_requests表的placement_id字段没有索引,关联操作(比如嵌套循环)会异常低效。此外,若site_id=3对应的placement数量庞大,关联后的数据量大幅增加,后续GROUP BY聚合操作的成本也会显著上升。
  3. 统计信息偏差导致执行计划不稳定
    查询耗时波动大(4-28秒),大概率是因为MySQL的表统计信息过时。优化器错误估计了site_id=3对应的行数,时而选择低效的嵌套循环连接,时而选择相对高效的哈希连接,导致耗时差异巨大。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 17:50:36