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

时间:2018-09-24 15:13:02

标签: sql-server parameters server null isnull

我正在尝试使用某些参数可以为NULL的SQL Server,其中NULL表示“忽略此参数”。

然后我有一个存储中间名的列,可以包含空值。

我具有以下条件,可以非常快速地工作:

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)    

谁能解释这两种方法之间的区别?

1 个答案:

答案 0 :(得分:0)

这是一个简短的摘要,说明了查询为什么会有不同的表现,以及如何帮助提高性能。有关更多详细信息,请参阅Gail Shaw的Catch-All QueriesRevisiting Catch-all Queries。有关详尽的分析,请参见Erland Sommarskog的Dynamic Search Conditions in T‑SQL

基本上,具有条件参数的查询试图创建一个查询计划,该计划适用于所有可能传入的参数组合。这意味着,如果仅传递可搜索的参数,则默认情况下不按索引查找查找。相反,它使用可用于任何参数组合的查询计划。

此问题的基本修补程序是

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

如果您需要详细的为什么和原因,以上文章非常好。