在以下查询中,只有title_deed
搜索条件才需要加入表title_deed_no
,并且不会从中选择任何字段。如果@titleDeedNumber
参数为null,是否仍会执行连接?这对性能有多大影响?我试图替换一个大丑陋的T-SQL字符串的动态生成,并且只有在提供title_deed_no
值的情况下,执行该操作的代码才会添加连接。
DECLARE @registrarId nchar(1)
DECLARE @titleDeedNumber nvarchar(50)
SELECT TOP 100
vw.*
FROM ACC.dbo.vw_Property_Nad vw
INNER JOIN title_deed td ON ( @titleDeedNumber IS NULL )
OR ( td.Prop_ID = vw.prop_id )
WHERE vw.Prop_ID IS NOT NULL
AND Registrar = isnull(@registrarId, vw.Registrar)
AND td.title_deed_no = isnull(@titleDeedNumber, td.title_deed_no)
我已经尝试过检查执行计划,但它只是忙于加入vw_Property_Nad
视图,我宁愿得到专家意见。
答案 0 :(得分:2)
在这种情况下,可能不是。
你最好用:
(vw.Registrar = @registrarId OR @registrarId IS NULL)
另外
我还会考虑IF或UNION ALL
SELECT
vw.*
FROM ACC.dbo.vw_Property_Nad vw
WHERE vw.Prop_ID IS NOT NULL
AND (vw.Registrar = @registrarId OR @registrarId IS NULL)
AND @titleDeedNumber IS NULL
UNION ALL
SELECT
vw.*
FROM ACC.dbo.vw_Property_Nad vw
WHERE vw.Prop_ID IS NOT NULL
AND (vw.Registrar = @registrarId OR @registrarId IS NULL)
AND @titleDeedNumber IS NOT NULL
AND EXISTS (...)
ORDER BY something
答案 1 :(得分:1)
我不确定您是否希望将联接优化掉。这意味着您将根据参数至少有两个不同的计划,这意味着如果提供参数并且缓存的计划与NULL
一起存储,它将不是最佳的(或者甚至可能是有效的)(或反之亦然)。如果这是您最终想要实现的目标,请使用两个不同的存储过程,让应用程序根据参数是否填充来决定调用哪个存储过程。
但只有在实际观察到重大的计划/绩效差异时才这样做。正如@gbn所述,我怀疑在这种情况下你会看到巨大的性能差异,除非标题契约表是巨大的且没有索引(或没有最佳索引)。典型的方法是比较值OR,检查值是否为NULL
。即使只有一个可选参数,多程序方法维护通常收效也很少,而且只需要一个可选参数即可复合。
有关非常好的背景阅读,请查看Erland Sommarskog关于Dynamic Search Conditions(2008-specific version)的文章。