Sql 扫描我希望看到的地方
我有一个表,table,在SQL Server数据库中有两列,PKColumn1和Column2。该表有一个聚集索引,聚集在PKColumn1上 如果对该表使用以下查询,我希望执行计划显示聚集索引搜索Sql 扫描我希望看到的地方,sql,sql-server,indexing,Sql,Sql Server,Indexing,我有一个表,table,在SQL Server数据库中有两列,PKColumn1和Column2。该表有一个聚集索引,聚集在PKColumn1上 如果对该表使用以下查询,我希望执行计划显示聚集索引搜索 SELECT PKColumn1 FROM Table WHERE PKColumn1 = 1 DECLARE @PKColumn1 INT = 1; SELECT PKColumn1 FROM Table WHERE (PKColumn1 = @PKColumn1 OR @PKColumn1
SELECT PKColumn1
FROM Table
WHERE PKColumn1 = 1
DECLARE @PKColumn1 INT = 1;
SELECT PKColumn1
FROM Table
WHERE (PKColumn1 = @PKColumn1 OR @PKColumn1 IS NULL)
它确实做到了
如果对该表使用以下查询,我还希望执行计划显示聚集索引Seek
SELECT PKColumn1
FROM Table
WHERE PKColumn1 = 1
DECLARE @PKColumn1 INT = 1;
SELECT PKColumn1
FROM Table
WHERE (PKColumn1 = @PKColumn1 OR @PKColumn1 IS NULL)
但是,我现在从执行计划中看到,该表已被扫描
这是为什么?在第二个查询中,问题在于where子句:
其中(PKColumn1=@PKColumn1或@PKColumn1为空)
SQL Server不执行任何短路(如在c#| | |),这意味着即使表达式@PKColumn1为NULL
计算结果为true,也不能保证SQL Server不会计算第二个表达式PKColumn1=@PKColumn1
解决方案:
处理这些可选参数的最佳方法是使用动态SQL并动态构建查询。像
DECLARE @PKColumn1 INT = 1
,@Sql NVARCHAR(MAX);
SET @Sql = N' SELECT PKColumn1
FROM Table
WHERE 1 = 1 '
+ CASE WHEN @PKColumn1 IS NOT NULL THEN
N' AND PKColumn1 = @PKColumn1 ' ELSE N'' END
Exec sp_executesql @Sql
,N'@PKColumn1 INT'
,@PKColumn1
使用sp_executesql将缓存参数化的执行计划。当您有两个以上的可选参数时,这通常是一个更大的问题 您正在使用哪个版本的sql