我正在尝试使用一些可以为 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)
谁能解释一下这两种方法有什么区别?
这是查询执行方式不同的原因以及您可以采取哪些措施来提高性能的简短摘要。有关更多详细信息,请参阅 Gail Shaw 的捕获全部查询和重新访问捕获全部查询。有关详尽的分析,请参阅 T-SQL 中的动态搜索条件 作者:Erland Sommarskog。
基本上,具有条件参数的查询会尝试创建一个查询计划,该计划适用于传入的所有可能的参数组合。这意味着,如果仅传入可查找参数,则不会默认按索引查找。相反,它使用一些可用于参数任意组合的查询计划。
此问题的基本修复程序是
- 在查询末尾添加
OPTION (RECOMPILE)
(仅限 SQL 2008 R2 SP1、2008 SP3 或更高版本( - 使用动态 SQL。仅添加使用非空参数检查的条件。
如果您想要完整的详细原因和原因,上面的文章非常好。