将 NULL 参数与可能包含 NULL 值的列进行比较

Compare NULL Parameters with columns that may contain NULL values

我正在尝试使用一些可以为 NULL 的参数在 SQL 服务器上工作,其中 NULL 表示 "ignore this parameter"。

然后我有存储中间名的列并且可以包含空值。

我有以下条件非常有效:

T.tr_ben_name           =   ISNULL(@BenFirstName,       T.tr_send_name)     AND
T.tr_ben_middle         =   ISNULL(@BenMiddleName,      T.tr_send_middle)   AND
T.tr_ben_last           =   ISNULL(@BenLastName,        T.tr_send_last)     AND
T.tr_ben_last2          =   ISNULL(@BenSecondLastName,  T.tr_send_last2 )

但是由于某些原因,如果中间名值和相应的参数都是 NULL,即使我关闭 ANSI NULLS,记录也会被跳过。

然后我想到了另一个运行良好但慢 4 倍的版本:

(T.tr_ben_name          =   @BenFirstName       OR  @BenFirstName       IS NULL)    AND
(T.tr_ben_middle        =   @BenMiddleName      OR  @BenMiddleName      IS NULL)    AND
(T.tr_ben_last          =   @BenLastName        OR  @BenLastName        IS NULL)    AND
(T.tr_ben_last2         =   @BenSecondLastName  OR  @BenSecondLastName  IS NULL)    

任何人都可以解释这两种方法之间的区别吗?

这是一个简短的总结,说明了查询执行不同的原因,以及您可以采取哪些措施来提高性能。有关详细信息,请参阅 Catch-All Queries and Revisiting Catch-all Queries by Gail Shaw. For an exhaustive analysis, see Dynamic Search Conditions in T‑SQL 作者 Erland Sommarskog。

基本上,带有条件参数的查询会尝试创建一个适用于所有可能的传入参数组合的查询计划。这意味着如果您仅传入可搜索参数,它不会默认按索引搜索进行查找.相反,它使用一些可用于任何参数组合的查询计划。

此问题的基本修复是

  1. 在您的查询末尾添加 OPTION (RECOMPILE)(仅限 SQL 2008 R2 SP1、2008 SP3 或更高版本)
  2. 使用动态 SQL。只添加非空参数检查的条件。

如果你想要完整详细的原因和原因,上面的文章非常好。