C# SqlCommand在为LIKE传递文本参数时显示性能不佳

C# SqlCommand在为LIKE传递文本参数时显示性能不佳,c#,.net,sql,ado.net,C#,.net,Sql,Ado.net,我遇到了一个非常棘手的问题: 我动态地生成SQLServer命令,其中一部分是一组类似的测试,用于对多个列和表进行文本搜索。它看起来像: SET @text = '%' + REPLACE(REPLACE(REPLACE(@text, '!', '!!'), '%', '!%'), '_', '!_') + '%' INSERT INTO @textFiltered FROM @documents d LEFT JOIN docData t1 WITH (NOLOCK)

我遇到了一个非常棘手的问题:

我动态地生成SQLServer命令,其中一部分是一组类似的测试,用于对多个列和表进行文本搜索。它看起来像:

SET @text = '%' + REPLACE(REPLACE(REPLACE(@text, '!', '!!'), '%', '!%'), '_', '!_') + '%'

INSERT INTO
  @textFiltered
FROM
  @documents d 
  LEFT JOIN docData t1 WITH (NOLOCK)
    ON t1.ID = d.ID AND
       (t1.Topic like @text escape '!'
        OR t1.Subject like @text escape '!')
  LEFT JOIN docData2 t2 WITH (NOLOCK)
    ON t2.ID = d.ID AND 
       t2.Name like @text escape '!'
WHERE
  t1.ID IS NOT NULL 
  OR t2.ID IS NOT NULL
(当然,这不是进行文本搜索的最佳方式,但这不是重点)

现在,当我在C#中创建SQLCommand时,如下所示:

using (var cmd = new SqlCommand())
{
   cmd.CommandText = cmdText;
   cmd.CommandType = CommandType.Text;
   cmd.Connection = connection;
   cmd.Parameters.Add("text", NVarChar, 4000).Value = searchText;
   var reader = cmd.ExecuteReader();
   ....
}
执行性能非常差(比如8秒),而在SQL Management Studio中执行同一查询的速度要快得多(比如500毫秒)。 但是,如果我没有将文本作为参数传递,而是将其嵌入到SQL的文本中:

DECLARE @text nvarchar(max)
SET @text = '<embedded-text>'
DECLARE@text-nvarchar(最大值)
设置@text=''
然后SqlCommand也运行得很快。 更奇怪的是,这种行为似乎与LIKE子句中使用的一组列相关(不知道如何)。这些列的类型可以是nvarchar(size)、nvarchar(max)、ntext

我怀疑问题出在参数上——可能是它的类型不正确,或者是其他原因


p.S.试图创建大小=搜索文本长度+1的参数-没有帮助。

我最好的猜测是,它与SQL Server为您选择的查询计划有关。 使用常量varchar(SQL server可以根据现有统计信息进行计算)和使用任意变量(服务器对其一无所知)之间有很大的区别

您可以尝试选项(重新编译)提示。尽管此提示将导致在每次调用时编译存储过程,但它也将允许SQL Server为给定值搜索最佳计划,在您的情况下,这可能是一个很好的权衡


您还可以为存储过程的两个选项添加查询计划,也许有人可以看到差异,并指出确切的问题。

您的
%
标记在哪里?%标记附加在SQL中。在sql文本中添加了一行附加符号,并在输入中屏蔽“%”、“"”符号。我遇到了类似的问题()。显然,SQL Server优化器有时会选择错误的查询计划:-(