4

I have a query of the form

SELECT DISTINCT Str,Score 
FROM Tab 
WHERE Str in ('Str1', 'Str2', 'Str3') AND Type = 0

Table schema is

  Str - varchar(8000)  
  Score - int  
  Type - bit  

I also have an index on Str which includes Type and Score

The number of strings in the IN vary

When I construct a direct query from C#, it's virtually instantaneous

When I use a parametrized query (using the method here https://stackoverflow.com/a/337792/508593 ), it becomes extremely slow -- the original query takes less than a second. This is timing out

Looking into SQL profiler and SSMS, the slowness seems to be due to the statement being wrapped in exec sp_executesql which causes an index scan instead of a seek. The direct query uses the index mentioned. With sp_executesql, the index does not

Is my suspicion correct and is there a way to resolve this?


In addition to the root cause specified by Martin, the solution was to explicitly set the parameter type using

command.Parameters[i].DbType = DbType.AnsiString;

Which forces varchar instead of nvarchar

4

3 回答 3

4

参数必须varchar不是nvarchar

否则查询将有效

WHERE IMPLICIT_CAST(Str AS NVARCHAR(4000)) in (@P1,@P2,@P3) AND Type = 0

这会损害索引的使用。

于 2013-10-18T10:09:54.320 回答
1

从您的问题中不清楚您采用了哪种参数化方法;您所指的问题显示了不同的方法。

如果您选择了表值参数解决方案,您可能会遇到由 SQL Server 创建的缓存查询计划,而不知道 TVP 参数中的项目数。默认情况下,IIRC 假设有 10'000 个项目,这将解释索引扫描而不是查找。

话虽如此,尝试OPTION (RECOMPILE)在参数化查询的末尾添加一个提示,这将使 SQL Server 能够使用(当时已知的)项目计数重新编译查询。

于 2013-10-18T10:06:19.047 回答
0

问题不在于参数化查询。

IN根据MSDN在您的子句中指定硬编码的值时,您最好对#values 有一个很好的估计:

在 IN 子句中包含大量值(数千个)会消耗资源并返回错误 8623 或 8632。要解决此问题,请将 IN 列表中的项目存储在表中

于 2013-10-18T10:09:30.677 回答