【发布时间】:2026-01-25 22:30:02
【问题描述】:
我在 T-SQL 中有一个简单的查询:
SELECT
*
FROM
Table t
WHERE
t.Column IN ( 'Value1', 'Value2', 'Value3', ..., 'ValueN' )
;
当然,查询实际上要复杂得多,有几个 JOIN 和子查询,但目前这无关紧要。
问题是: 以下哪项在性能方面更快?
(1)原始条件
t.Column IN ( 'Value1', 'Value2', 'Value3', ..., 'ValueN' )
(2) 使用只有一个名为 Value 的列(可能是主键)的表 ValueEnumeration,该表填充了值 'Value1'、'Value2'、...
SELECT
*
FROM
Table t
WHERE
t.Column in ( SELECT ve.Value FROM ValueEnumeration ve )
;
(3) 使用用户定义函数 (UDF),准确地说是标量函数,称为 IsAllowedValue。
功能:
CREATE FUNCTION dbo.IsAllowedValue ( @ValueToCheck VARCHAR(20) ) RETURNS INT
AS
BEGIN
IF @ValueToCheck = 'Value1'
OR @ValueToCheck = 'Value2'
OR @ValueToCheck = 'Value3'
...
OR @ValueToCheck = 'ValueN'
BEGIN
RETURN 1;
END;
RETURN 0;
END
;
查询:
SELECT
*
FROM
Table t
WHERE
dbo.IsAllowedValue(t.Column) = 1
;
嗯,我想第一个将是最快的解决方案。但是,我需要在存储过程的许多地方执行类似的检查。一旦值的原始枚举在未来发生变化(这很可能发生 - 例如,必须向其中添加一个新值),您将必须转到代码中原始条件的所有出现并添加新的那里的价值。因此,我决定采用更可重用的解决方案。但我不知道该选择哪一个。我有时需要反过来做一个测试(WHERE t.Column NOT IN (...))。我还想到在INNER JOIN(用于肯定检查)或LEFT OUTER JOIN(用于否定检查)中使用表ValueEnumeration,但这实施起来会很痛苦,因为我有大约。代码中有 50 个此类条件的位置,一般来说,添加 JOIN 会极大地改变 SQL 查询的外观以及执行计划,后者并不总是好的。
你有什么想法吗?
【问题讨论】:
-
我想
n > 202 最快,3 最慢(因为函数很慢并且需要全表扫描)。虽然 - 关于性能的声明本质上是有缺陷的,我建议您自己检查一下。 -
Race your horses.。直观地说,从可读性和性能的角度来看,第一个选项是最好的机器人。
-
@Ginden 我目前在 ValueEnumeration 表中有大约 15 个值。谢谢你的评论。你是对的。我将不得不自己尝试所有选项...
-
你在
column上有一个INDEX吗?
标签: sql sql-server optimization where-clause