两列值之间具有常量的 SQL 查询

问题描述 投票:0回答:1

我被要求处理一些昂贵的 SQL Server 查询,以提高它们的效率,但我对他们告诉我的一些事情感到困惑。我不确定我是否获得了正确的信息。 (无论如何,我可以看到该计划,但我不太熟悉如何理解它。)向我发送笔记的人已经去度假了,所以我现在无法要求他们澄清.

他们记下的问题之一是“在左侧的 where 子句中使用变量而不是实际的表列名称”。我唯一能看到他们可能指的是这样的东西(作为更大查询的一部分):

SELECT Column_1, Column_2  
FROM Table_1
WHERE 500 BETWEEN Min_Value AND Max_Value

现在,我明白

BETWEEN
是一个快捷方式,这实际上翻译为

WHERE 500 >= Min_Value AND 500 <= Max_Value

这真的是 SQL Server 中的问题吗?更具可读性的

WHERE 500 BETWEEN Min_Value AND Max_Value
真的会比
WHERE Min_Value <= 500 AND Max_Value>= 500
花费更多吗?

或者我完全误解了他们在这里告诉我的内容?

sql sql-server query-optimization
1个回答
0
投票

之间没有性能差异

WHERE 500 BETWEEN Min_Value AND Max_Value

WHERE 500 >= Min_Value AND 500 <= Max_Value

但是,我经常看到 SQL 代码在不必要的情况下更改原始列值,这可能是一个问题。

例如,在检查日期时间列是否属于范围的一部分时,这种情况尤其常见。我一直看到这样的代码:

CAST(MyDateTimeColumn As Date) BETWEEN @StartDate AND @EndDate

但这不好。您现在需要对

表中的每一行
进行DATE转换,甚至是您最终不需要的行,因为在完成转换之前您无法知道该值是否与条件匹配。而且情况会变得更糟:该列上的任何索引对于该查询来说都是毫无价值的,因为转换结果中的值不再与索引中存储的值匹配。

更好的表达方式是这样的:

MyDateTimeColumn >= @StartDate AND MyDateTimeColumn < DATEADD(day, 1, @EndDate)

这使用了半开范围,其中上限是范围收盘后天的唯一边界。通过这种方式,我们使用原始且未更改的列值,这保留了使用索引的能力并避免了对整个表的每行操作。

我们可以进一步概括这一点:

只要您可以重写表达式以避免对列数据进行操作并调整输入条件,您就可能获得巨大的性能优势。

© www.soinside.com 2019 - 2024. All rights reserved.