使用参数化查询时,SQL 查询速度极慢

本文关键字:查询 SQL 速度 参数 | 更新日期: 2023-09-27 18:35:51

>我有一个表单查询

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

表架构为

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

我还有一个关于Str的索引,其中包括TypeScore

IN中的字符串数量各不相同

当我从 C# 构造直接查询时,它几乎是即时的

当我使用参数化查询(使用此处的方法 https://stackoverflow.com/a/337792/508593)时,它变得非常慢 - 原始查询不到一秒钟。这是超时

查看 SQL 探查器和 SSMS,速度缓慢似乎是由于语句被包装在 exec sp_executesql 中,这会导致索引扫描而不是查找。直接查询使用提到的索引。使用sp_executesql,索引不会

我的怀疑是否正确,有没有办法解决这个问题?


除了 Martin 指定的根本原因之外,解决方案是使用

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

这迫使瓦尔查尔而不是 nvarchar

使用参数化查询时,SQL 查询速度极慢

参数

需要varchar而不是nvarchar

否则,查询将有效

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

这损害了索引的使用。

从你的问题中不清楚你采取了什么参数化方法; 你提到的问题显示了不同的方法。

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

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

问题不在于参数化查询。

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

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