扫描我希望看到的地方

时间:2017-01-25 11:13:44

标签: sql sql-server indexing

我有一个表Table,在SQL Server数据库中有两列,PKColumn1和Column2。该表有一个聚簇索引,聚集在PKColumn1上。

如果我对这个表使用以下查询,我希望执行计划显示一个Clustered Index Seek。

SELECT PKColumn1
FROM Table
WHERE PKColumn1 = 1
它适当地做了。

如果我对这个表使用以下查询,我也希望执行计划显示一个Clustered Index Seek。

DECLARE @PKColumn1 INT = 1;
SELECT PKColumn1
FROM Table
WHERE (PKColumn1 = @PKColumn1 OR @PKColumn1 IS NULL)

但是我现在从执行计划中看到该表已经扫描

为什么会这样?

1 个答案:

答案 0 :(得分:3)

在您的第二个查询中,问题出在您的where子句中:

WHERE (PKColumn1 = @PKColumn1 OR @PKColumn1 IS NULL)

SQL Server不做任何短路(如c#||),这意味着即使表达式@PKColumn1 IS NULL的计算结果为true,也无法保证sql server不会计算第二个表达式{{1 }}

<强>解决方案:

处理此类可选参数的最佳方法是使用动态SQL并动态构建查询。像......那样......

PKColumn1 = @PKColumn1

使用sp_executesql将缓存参数化的执行计划。当您有两个以上的可选参数时,这通常是个问题。