2012-07-27 86 views
3

优化器似乎对varchar参数的空能力感到困惑,我不知道为什么。我正在使用SQL Server 2008 btw。所有被查询的列都被编入索引。 TDate列是一个聚集的分区索引。 FooValue列是索引的,不可为空的列。SQL Server 2008存储过程 - 优化器认为我的参数可以为空

例子:

CREATE PROCEDURE dbo.MyExample_sp @SDate DATETIME, @EDate DATETIME, @FooValue VARCHAR(50) 
AS 
SET NOCOUNT ON 

--To avoid parameter spoofing/sniffing 
DECLARE @sDate1 DATETIME, @eDate1 DATETIME 
SET @sDate1 = @sDate 
SET @eDate1 = @eDate 

SELECT 
    fd.Col1, 
    fd.Col2, 
    fd.TDate, 
    fl.FooValue, 
    fd.AccountNum 
FROM dbo.FooData fd 
INNER JOIN dbo.FooLookup fl 
    ON fl.FL_ID = fd.FL_ID 
WHERE fd.TDate >= @sDate1 
    AND fd.TDate < @eDate1 
    AND fl.FooValue = @FooValue 

运行此作为查询按预期工作。所有索引都是搜索引擎,没有欺骗等。通过执行sproc执行此操作需要20倍的时间 - 相同的查询 - 相同的参数。但是,如果我做出以下更改(非常最后一行),一切都可以再次发挥作用。

CREATE PROCEDURE dbo.MyExample_sp @SDate DATETIME, @EDate DATETIME, @FooValue VARCHAR(50) 
AS 
SET NOCOUNT ON 

--To avoid parameter spoofing/sniffing 
DECLARE @sDate1, @eDate1 
SET @sDate1 = @sDate 
SET @eDate1 = @eDate 

SELECT 
    fd.Col1, 
    fd.Col2, 
    fd.TDate, 
    fl.FooValue, 
    fd.AccountNum 
FROM dbo.FooData fd 
INNER JOIN dbo.FooLookup fl 
    ON fl.FL_ID = fd.FL_ID 
WHERE fd.TDate >= @sDate1 
    AND fd.TDate < @eDate1 
    AND fl.FooValue = ISNULL(@FooValue, 'testthis') 

这就好像优化器对参数是否为空或者是不是很困惑?另外,向参数添加默认值也没有什么区别。除非我使用= isnull(@参数,'一些常量'),否则它仍然需要永久运行。

我很高兴我明白了这一点。但是,我想了解为什么会发生这种情况,以及是否有更加优雅的方式来解决问题。

+0

变量*为*可空。你的问题是为什么一个可为空的变量影响查询计划?或者为什么变量被认为是可空的? – 2012-07-27 21:51:37

+0

我想这应该是后者。现在我已经遇到了这个问题,我可以明白为什么这个变量被认为是空的(当然我可以传入一个空值)。 但是,为什么查询计划全部搞砸了让我感到困惑。 PS:有没有更好的方法来告诉SQL一个变量不能为空?感谢你的协助! – maplemale 2012-07-27 22:05:00

+0

一种方法是将查询写为动态SQL,并将变量硬编码为字符串中的值。当你运行字符串时,它会在那个时候被编译,所以它应该选择最佳的查询计划。 – 2012-07-27 22:24:25

回答

2

回复:可空变量

有在T-SQL变量无可空的概念,你可以使用C#中的定义一个变量可为空的方式? 如果您在存储过程中有参数,最终用户可以将他或她想要的任何内容传递给存储过程,无论是真实值还是空值。

回复:查询计划

查询计划,将获得缓存是获取在第一时间生成的查询计划调用此存储过程。所以,如果你在@FooValue空传递第一次运行它时,它会针对@FooValue = null进行优化。

有一个OPTIMIZE FOR提示,你可以用它来优化查询其他一些价值:

或者你可以使用WITH RECOMPILE,这将迫使查询计划获得再生的存储过程的每次运行。

显然在使用这些类型的提示时存在权衡,因此在使用这些提示之前一定要理解它们。

相关问题