我有一个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%。
有时价值为空,我必须保持这样。
有人可以解释一下吗?可以修复吗?
感谢。
答案 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_2
或col_3,col_4,col_2
上的索引。将col_2
放在索引定义的最后。它将在两种情况下有效使用(OPTION(RECOMPILE)
)。