当搜索条件值为空时,查询计划显示 99% 的键查找

query plan shows key lookup with 99% when search condition value is null

我有一个 SP,该 sp 在 table 上执行,索引在三列 col_1、col_2、col_3、col_4、col_n。 Col 1 是一个身份。在 col_2、col_3、col_4 上有一个索引。

当我查询类似

的内容时
@parameter=1

SELECT col_2,col_3,col_4
WHERE col_2=@parameter
AND col_3='2'
AND col_4=10.00

它使用我之前提到的索引,但如果我查询类似

@paramete =null; -- the parameter is null in this case when parameter
has value it uses the index

SELECT col_2,col_3,col_4
WHERE (@parameter is null OR col_2 = @parameter)
AND col_3='2'
AND col_4=10.00

它显示了一个查询计划,其中一个键在 col_1 上查找,成本为 99%。

有时值为空,我必须保持这样。

有人可以解释一下吗?可以修复吗?

谢谢。

首先,在查询中添加OPTION(RECOMPILE)

SELECT col_2,col_3,col_4
WHERE 
    (@parameter is null OR col_2 = @parameter)
    AND col_3='2'
    AND col_4=10.00
OPTION(RECOMPILE);

有关详细信息,请参阅 Erland Sommarskog 的优秀文章 Dynamic Search Conditions in T‑SQL


如果 @parameter 不是 NULL,使用 OPTION(RECOMPILE) 查询有效地变为:

SELECT col_2,col_3,col_4
WHERE 
    col_2 = <actual_parameter_value>
    AND col_3='2'
    AND col_4=10.00

col_2,col_3,col_4 上的索引可用于快速查找此查询中的必要行。


如果 @parameter 为 NULL,使用 OPTION(RECOMPILE) 查询有效地变为:

SELECT col_2,col_3,col_4
WHERE 
    col_3='2'
    AND col_4=10.00

现在很明显 col_2,col_3,col_4 上的索引在这里没有帮助。您需要 col_3,col_4 include (col_2) 上的第二个索引以使其高效。


另一方面,具有不同列顺序的单个索引在这两种情况下都会有所帮助。因此,不是在 col_2,col_3,col_4 上创建索引,而是在 col_4,col_3,col_2col_3,col_4,col_2 上创建索引。将 col_2 放在索引定义的最后。它将在两种情况下有效使用(OPTION(RECOMPILE))。