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

SQL查询性能优化:该场景下用UNION替代WHERE子句中的OR是否可行?

SQL查询性能优化方案

核心优化方案验证

你提出的将WHERE子句中的OR替换为UNION的思路完全可行,是当前场景的核心优化方向:原有OR逻辑会导致数据库无法命中Tool表的联合索引,需要全表扫描匹配两种分支条件,拆分后两个独立查询可以各自命中索引,大幅降低数据扫描量。

额外优化点

  • 移除子查询中的字段函数转换:将convert(datetime, subTool.DateTime, 120) < @ToolDateTime调整为直接匹配subTool.DateTime < @ToolDateTime,提前对@ToolDateTime做格式适配即可,避免字段上的函数运算导致索引失效。
  • 新增覆盖式联合索引:Tool表新增索引(CustomerId, ToolTypeId, ToolId, Is_Active, InterviewId, DateTime, StartDate, EndDate, Id),覆盖所有查询、排序字段,实现索引覆盖无需回表查询。
  • 子查询结果提前提取:将OR分支中的子查询提前提取为变量,避免重复执行计算。
  • 替换UNION为UNION ALL:两个查询分支通过InterviewId = @InterviewId和InterviewId != @InterviewId实现互斥,不存在重复数据,无需UNION的去重步骤,性能可进一步提升。
  • 避免SELECT *写法:按需指定返回字段,减少数据传输开销,也更容易实现索引覆盖。

优化后参考SQL

-- 提前提取子查询结果
DECLARE @TargetToolId INT
SELECT TOP 1 @TargetToolId = SubTool.Id
FROM Tool SubTool
INNER JOIN Interview subInterview ON subInterview.Id = SubTool.ToolId 
WHERE SubTool.ToolTypeId = @ToolTypeId
AND SubTool.Is_Active = 1  
AND SubTool.InterviewId != @InterviewId  
AND SubTool.ToolId = @ToolId
AND SubTool.CustomerId = @CustomerId
AND SubTool.DateTime < @ToolDateTime
ORDER BY SubTool.DateTime DESC, SubTool.StartDate DESC, SubTool.EndDate, SubTool.Id DESC

-- 拼接两个查询分支
SELECT Tool.*, Interview.*
FROM Tool
INNER JOIN Interview ON Interview.Id = Tool.InterviewId
WHERE Tool.ToolTypeId = @ToolTypeId 
AND Tool.Is_Active = 1
AND Tool.InterviewId = @InterviewId
AND Tool.ToolId = @ToolId
AND Tool.CustomerId = @CustomerId

UNION ALL

SELECT Tool.*, Interview.*
FROM Tool
INNER JOIN Interview ON Interview.Id = Tool.InterviewId
WHERE Tool.Id = @TargetToolId

ORDER BY StartDate, Id

内容的提问来源于stack exchange,提问作者JoãoEs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 17:24:01