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

为何同一条SQL查询在MSSQL运行正常,MySQL却卡顿耗时久?

问题原因分析
  • 你此前看到的“非相关子查询导致效率低”的说法存在错误,该SQL实际使用的是相关子查询:外层查询每扫描1行MyTable的记录,就会触发1次内层子查询执行,匹配当前行的location、item值查找符合要求的最大日期。当数据量达到50万级时,相当于要执行近50万次子查询,性能自然急剧下降。
  • MSSQL的查询优化器内置了更完善的子查询扁平化逻辑,会自动将这种相关子查询重写成效率更高的关联查询执行计划,所以不会出现性能问题;而MySQL(尤其是5.7及更早版本)的优化器对这类场景的重写支持较差,会严格按照嵌套逻辑逐行执行,因此耗时极长。
  • 1000行小数据量下子查询执行次数少,所以感知不到性能差异。
优化方案

你可以根据自己的MySQL版本选择对应写法,两种写法的返回结果都和预期完全一致:

方案1:MySQL 8.0+ 窗口函数写法(性能最优、代码最简洁)

仅需扫描1次表即可得到结果,性能远高于原相关子查询写法:

SELECT location, item, cost, date
FROM (
    SELECT 
        location, item, cost, date,
        ROW_NUMBER() OVER (
            PARTITION BY location, item 
            ORDER BY date DESC, cost DESC
        ) AS rn
    FROM MyTable
    WHERE date <= '2021/10/31' AND cost <> 0
) t
WHERE rn = 1;

方案2:兼容MySQL 5.7及更低版本的关联写法

如果你的MySQL版本不支持窗口函数,可以使用两次表扫描的关联写法,性能也远高于原嵌套写法:

SELECT t.location, t.item, MAX(t.cost) AS cost, t.date
FROM MyTable t
INNER JOIN (
    SELECT location, item, MAX(date) AS max_date
    FROM MyTable
    WHERE date <= '2021/10/31' AND cost <> 0
    GROUP BY location, item
) md ON t.location = md.location AND t.item = md.item AND t.date = md.max_date
WHERE t.cost <> 0
GROUP BY t.location, t.item, t.date;
额外性能优化建议

新建以下覆盖联合索引后,上述两种写法都不需要回表查询,性能可以再提升数倍:

CREATE INDEX idx_loc_item_date_cost ON MyTable (location, item, date DESC, cost);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:54:04