如果不需要,SQL Server 2008会优化连接吗?

时间:2011-09-05 18:18:31

标签: sql-server tsql sql-server-2008

在以下查询中,只有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视图,我宁愿得到专家意见。

2 个答案:

答案 0 :(得分:2)

在这种情况下,可能不是。

你最好用:

  • EXISTS not JOIN(即半连接不等于连接)
  • (vw.Registrar = @registrarId OR @registrarId IS NULL)
  • 同样在EXISTS中的td.title_deed_no

另外

  • 没有ORDER BY的TOP是没用的
  • 您的加入条件意味着CROSS JOIN - >你需要DISTINCT才能让它运作
  • vw意味着视图 - >查询比您期望的更复杂。视图是一个扩展的宏

我还会考虑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 Conditions2008-specific version)的文章。