使用参数化查询时,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
的索引,其中包括Type
和Score
IN
中的字符串数量各不相同
当我从 C# 构造直接查询时,它几乎是即时的
当我使用参数化查询(使用此处的方法 https://stackoverflow.com/a/337792/508593)时,它变得非常慢 - 原始查询不到一秒钟。这是超时
查看 SQL 探查器和 SSMS,速度缓慢似乎是由于语句被包装在 exec sp_executesql
中,这会导致索引扫描而不是查找。直接查询使用提到的索引。使用sp_executesql
,索引不会
我的怀疑是否正确,有没有办法解决这个问题?
除了 Martin 指定的根本原因之外,解决方案是使用
command.Parameters[i].DbType = DbType.AnsiString;
这迫使瓦尔查尔而不是 nvarchar
需要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 列表中