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

时间:2016-10-25 18:36:28

标签: sql sql-server performance sql-server-2014 sql-execution-plan

我有一个SP,sp执行在一个表上,索引有三列col_1,col_2,col_3,col_4,col_n。第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%。

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

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

感谢。

1 个答案:

答案 0 :(得分:0)

首先,将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))。