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

带同表聚合子查询的SQL调优:大表查询性能提升求助

SQL查询性能优化方案(针对2000万条数据的table1)

嘿,我来帮你拆解这个慢查询的问题!你的查询耗时30秒,核心是两个致命性能瓶颈,我们一步步来优化:

1. 先修复最严重的笛卡尔积问题

你原查询里from table1 t1, table2 t3没有写任何关联条件,这会生成2000万 × 1万 = 200亿条临时数据,后续的distinct还要对这么大数据去重,这绝对是性能杀手!首先必须补上t1和t3的关联条件,比如假设它们通过code关联,那要写成JOIN table2 t3 ON t1.code = t3.code(根据实际业务逻辑调整关联字段)。

2. 替换低效的关联子查询

原查询里的(select min(t2.dat) from table1 t2 where t2.code=t1.code)是关联子查询,会对table1的每一行单独执行一次min计算——2000万条数据就等于全表扫2000万次,这完全没必要。我们可以提前用分组查询算出每个code的最小日期,再和原表关联:

优化后的查询语句(用CTE提前计算)

DECLARE @PreviousMonthDate DATETIME;
-- 简化上月初日期的计算方式
SET @PreviousMonthDate = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1, 0);

-- 提前计算每个code的最小日期,过滤出符合条件的code
WITH CodeValid AS (
    SELECT code
    FROM table1
    GROUP BY code
    HAVING MIN(dat) > @PreviousMonthDate
)
-- 关联查询获取所需字段,注意补上t1和t3的关联条件
SELECT DISTINCT t1.code, t1.ent, t3.lib, t3.typ
FROM CodeValid cv
JOIN table1 t1 ON cv.code = t1.code
JOIN table2 t3 ON t1.code = t3.code -- 这里替换成实际的关联字段!

如果t1.ent、t3.lib、t3.typ对于每个code都是唯一值,那DISTINCT可以直接去掉,进一步减少开销。

3. 加索引加速查询

索引是大数据量查询的关键,针对这个场景建议创建两个复合索引:

  • 给table1的code和dat建索引,包含需要查询的ent字段,这样分组计算min(dat)时直接走索引,不用扫全表:
CREATE NONCLUSTERED INDEX IX_table1_code_dat_ent 
ON table1 (code) 
INCLUDE (dat, ent);
  • 给table2的关联字段(比如code)建索引,包含lib、typ字段,加速连接查询:
CREATE NONCLUSTERED INDEX IX_table2_code_lib_typ 
ON table2 (code) 
INCLUDE (lib, typ);

4. 额外优化建议

  • 查看执行计划:在SSMS里按Ctrl+M打开实际执行计划,看看是否还有全表扫描、哈希匹配(笛卡尔积残留)等问题,针对性调整。
  • 避免不必要的字段:如果table1或table2有其他冗余字段,不要在查询中返回,减少数据传输量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:54:16