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

SQL左连接两张万行表执行超60秒,如何优化至5秒以内?

性能瓶颈分析

  • 最大开销来自WHERE子句的相关子查询:每扫描table1的一行数据,就要执行一次子查询计算同key2_Table1分组下的最大时间,1万行数据就会触发1万次循环查询,是耗时超标的核心原因。
  • 缺少对应索引:两张表的连接键、分组计算键没有索引的情况下,每次查询都要做全表扫描,进一步放大了开销。
  • 全字段查询:SELECT t.*,k.*拉取了所有冗余字段,增加了数据读取、传输和临时缓存的开销,尤其table2有50+字段,冗余数据占比极高。

优化方案

1. 改写SQL,替换相关子查询为窗口函数

用窗口函数一次性完成所有行的分组排序,只需要扫描一次table1即可筛选出每个key2_Table1分组下的最新时间行,避免逐行循环查询。改写后的SQL如下:

WITH latest_table1 AS (
    SELECT 
        -- 请替换为你实际需要的table1字段,禁止用*拉取全字段
        key_Table1, key2_Table1, Time, [其他你需要的table1字段],
        ROW_NUMBER() OVER (PARTITION BY key2_Table1 ORDER BY Time DESC) AS rn
    FROM table1
)
SELECT 
    -- 请替换为你实际需要的两个表的字段,禁止用*拉取全字段
    lt.*, k.[需要的table2字段1], k.[需要的table2字段2], ...
FROM latest_table1 AS lt
LEFT JOIN table2 AS k 
    ON lt.key_Table1 = k.Key_Table2
WHERE lt.rn = 1
ORDER BY lt.Time;

如果存在同一个key2_Table1有多条相同最大Time数据都需要保留的场景,把ROW_NUMBER替换为RANK即可。

2. 新增覆盖索引,消除全表扫描

在SQL Server中创建以下两个索引,直接通过索引就能完成分组筛选、连接匹配操作,无需回表读取数据:

  • table1索引:CREATE NONCLUSTERED INDEX idx_table1_key2_time ON table1 (key2_Table1, Time DESC) INCLUDE (key_Table1, [其他你在SELECT中用到的table1字段])
  • table2索引:CREATE NONCLUSTERED INDEX idx_table2_key ON table2 (Key_Table2) INCLUDE ([其他你在SELECT中用到的table2字段])

3. 移除冗余字段查询

严格按照实际需求列明查询字段,不要用*拉取全部字段,仅这一项优化通常就能减少30%以上的执行耗时。

以上优化全部完成后,1万行级别的数据量执行时间可稳定控制在1秒以内,完全满足5秒以内的要求。你碰到的SQL Server执行速度慢于Excel的反常情况,核心原因是原SQL的不合理写法带来的额外计算开销,优化后SQL Server的执行速度会远快于Excel处理同需求的速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 02:42:00