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

排序与并行致SQL查询耗时过高,大数据集慢20-30倍求优化

优化你的SQL查询:大数据集下性能暴跌的原因和解决方案

首先,咱们直接揪出最可能的性能杀手:JOIN条件里的OR逻辑。你看这个连接:

LEFT OUTER JOIN ( SELECT [DESIGNATION], [TYPE], [BLDG], [LOCATION_ID] FROM [LTS].[dbo].[LTS_LOCATION] ) b 
ON a.[LAST_SEEN_LOC_ID] = b.[LOCATION_ID] OR b.[LOCATION_ID] = c.[LOCATION_ID]

这个OR在大数据集下是致命的——数据库没办法为这个条件使用有效的索引,只能做大量的行匹配(甚至是笛卡尔积级别的比对)。小数据集(1万行)的时候数据量小,这种开销不明显,但到50万+行时,计算量直接呈指数级增长,这就是你看到资源占用飙到20000、速度慢20-30倍的核心原因。

接下来,咱们一步步优化:

1. 重构OR连接条件,避免索引失效

把带OR的LEFT JOIN拆成两个独立的LEFT JOIN,然后用UNION ALL合并结果(如果有重复行可以用UNION,但UNION ALL更快)。这样数据库可以分别为每个JOIN条件利用索引,大幅减少匹配开销。

2. 去掉不必要的子查询

你现在用的子查询(比如SELECT ... FROM LTS_CONTAINER)完全没必要,直接JOIN原表即可。子查询会限制SQL Server优化器的执行计划选择,直接JOIN原表能让优化器更好地评估连接顺序和索引使用。

3. 添加针对性的索引

针对JOIN列、WHERE过滤列、ORDER BY列创建非聚集索引,让数据库快速定位数据:

  • 对LTS_PACKAGE的JOB_NUMBER、LAST_SEEN_LOC_ID、CONTAINER_ID创建复合索引(包含查询需要的其他列更好,即覆盖索引)
  • 对LTS_LOCATION的LOCATION_ID、TYPE创建索引,包含DESIGNATION、BLDG
  • 对LTS_DISCRETE_JOB_SUMMARY的DISCRETE_JOB_NUMBER、PLANNED_MFG_DELIVERY_DATE创建索引,包含其他需要的列
  • 对LTS_CONTAINER的CONTAINER_ID创建索引,包含DESIGNATION、LOCATION_ID

4. 优化后的查询示例

SELECT 
    a.[RFIDTAGID], 
    a.[JOB_NUMBER], 
    d.[PROJECT_NUMBER], 
    a.[PART_NUMBER], 
    a.[QUANTITY], 
    b.[DESIGNATION] as LOCATION, 
    c.[DESIGNATION] as CONTAINER, 
    a.[LAST_SEEN_TIME], 
    b.[TYPE], 
    b.[BLDG], 
    d.[PBG], 
    d.[PLANNED_MFG_DELIVERY_DATE], 
    d.[EXTENSION_DATE], 
    a.[ORG_ID] 
FROM [LTS].[dbo].[LTS_PACKAGE] as a 
LEFT OUTER JOIN [LTS].[dbo].[LTS_CONTAINER] c 
    ON a.[CONTAINER_ID] = c.[CONTAINER_ID]
LEFT OUTER JOIN [LTS].[dbo].[LTS_LOCATION] b 
    ON a.[LAST_SEEN_LOC_ID] = b.[LOCATION_ID]
INNER JOIN [LTS].[dbo].[LTS_DISCRETE_JOB_SUMMARY] d 
    ON a.[JOB_NUMBER] = d.[DISCRETE_JOB_NUMBER]
WHERE 
    d.[PLANNED_MFG_DELIVERY_DATE] <= GETDATE() 
    AND b.[TYPE] NOT IN('MFG', 'Manufacturing') 
    AND (b.[DESIGNATION] IS NOT NULL OR c.[DESIGNATION] IS NOT NULL)

UNION ALL

SELECT 
    a.[RFIDTAGID], 
    a.[JOB_NUMBER], 
    d.[PROJECT_NUMBER], 
    a.[PART_NUMBER], 
    a.[QUANTITY], 
    b.[DESIGNATION] as LOCATION, 
    c.[DESIGNATION] as CONTAINER, 
    a.[LAST_SEEN_TIME], 
    b.[TYPE], 
    b.[BLDG], 
    d.[PBG], 
    d.[PLANNED_MFG_DELIVERY_DATE], 
    d.[EXTENSION_DATE], 
    a.[ORG_ID] 
FROM [LTS].[dbo].[LTS_PACKAGE] as a 
LEFT OUTER JOIN [LTS].[dbo].[LTS_CONTAINER] c 
    ON a.[CONTAINER_ID] = c.[CONTAINER_ID]
LEFT OUTER JOIN [LTS].[dbo].[LTS_LOCATION] b 
    ON b.[LOCATION_ID] = c.[LOCATION_ID]
INNER JOIN [LTS].[dbo].[LTS_DISCRETE_JOB_SUMMARY] d 
    ON a.[JOB_NUMBER] = d.[DISCRETE_JOB_NUMBER]
WHERE 
    d.[PLANNED_MFG_DELIVERY_DATE] <= GETDATE() 
    AND b.[TYPE] NOT IN('MFG', 'Manufacturing') 
    AND (b.[DESIGNATION] IS NOT NULL OR c.[DESIGNATION] IS NOT NULL)
    AND a.[LAST_SEEN_LOC_ID] != b.[LOCATION_ID] -- 避免和第一个查询重复
ORDER BY [JOB_NUMBER], d.[PLANNED_MFG_DELIVERY_DATE] desc, [RFIDTAGID];

额外建议

  • 更新统计信息:执行UPDATE STATISTICS [LTS].[dbo].[LTS_PACKAGE](以及其他涉及的表),过时的统计信息会让SQL Server优化器选错执行计划。
  • 查看执行计划:在SQL Server Management Studio里点击“显示估计的执行计划”,看看有没有全表扫描、哈希匹配(如果可以用嵌套循环或合并连接更好)的操作,这些都是性能瓶颈的信号。

内容的提问来源于stack exchange,提问作者Ben F.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:29:16