不知道从哪里开始--不确定问题是我在愚弄查询优化器,还是在涉及nulls时索引的工作方式固有的问题。
我遵循的一个编码约定是编写这样的存储过程:
declare procedure SomeProc
  @ID int = null
as
  select
    st.ID,st.Col1,st.Col2
  from
    SomeTable st
  where
    (st.ID = @ID or @ID is null) --works, but very slow (relatively)当然,在这个简单的测试用例中不太有用,但是当您希望存储的proc对满足某些条件的整个表或行进行操作时,它在其他场景中很有用。但是,在更大的桌子上使用是很慢的.如果我将where子句替换为:
where
    st.ID = @ID --3-5x faster than first example更让我困惑的是,用-1替换空的速度与上面的“固定”WHERE子句的速度几乎相同:
declare procedure SomeProc
  @ID int = -1
as
  select
    st.ID,st.Col1,st.Col2
  from
    SomeTable st
  where
    (st.ID = @ID or @ID=-1) --much better... but why?很明显,使事情变得古怪的是零,但为什么,确切地说呢?对我来说,从执行计划上看,答案并不明确。多年来,我在各种数据库、表和Server版本上都注意到了这一点,所以我不认为这是我当前环境的怪癖。我已经通过将缺省参数值从null转换为-1来解决这个问题;我的问题是为什么会工作。
备注
发布于 2009-12-20 19:34:44
你有很多问题,很有可能
但没有看到这些计划,这些都是有根据的猜测。
参数嗅探
..。默认的"NULL“。尝试使用不同的默认值,例如-1或没有默认设置。
缺省值为NULL的@ID = -1,参数嗅探=普通检查,因此速度更快。
您还可以在Server 2008中尝试使用未知数优化
OR运算符
一些想法..。
如果列不可空,则在大多数情况下,优化器将忽略该条件。
st.ID = ISNULL(@ID, st.ID)此外,还可以使用IF语句。
IF @ID IS NULL
   SELECT ... FROM...
ELSE
   SELECT ... FROM... WHERE st.ID或者以类似的方式联合起来。
就我个人而言,在大多数情况下,我会使用参数掩蔽(总是)和ISNULL (我会先尝试)。
alter procedure SomeProc
  @ID int = NULL
AS
declare @maskID int
select @maskID = @ID
...https://stackoverflow.com/questions/1936685
复制相似问题