LINQ to实体中的string.contains导致执行速度非常慢

时间:2012-08-30 11:14:02

标签: sql-server entity-framework-4

这个LINQ表达式:

var result = entities.Cases
            .Where(c => c.House.Address.Contains("otte"))
            .ToList();

在服务器上执行此sql:

SELECT 
...
--rows
...
FROM  [dbo].[Case] AS [Extent1]
INNER JOIN [dbo].[House] AS [Extent2] ON [Extent1].[HouseID_FK] = [Extent2].[HouseID]
WHERE [Extent2].[Address] LIKE '%otte%'

这需要大约100毫秒才能完成。

这个LINQ表达式:

var value = "otte";
var result = entities.Cases
            .Where(c => c.House.Address.Contains(value))
            .ToList();

在服务器上执行此sql:

exec sp_executesql N'SELECT 
...
--rows
...
FROM  [dbo].[Case] AS [Extent1]
INNER JOIN [dbo].[House] AS [Extent2] ON [Extent1].[HouseID_FK] = [Extent2].[HouseID]
WHERE [Extent2].[Address] LIKE @p__linq__0 ESCAPE N''~''',N'@p__linq__0     nvarchar(4000)',@p__linq__0=N'%otte%'

这需要大约1400毫秒才能完成。

如果我将“value”声明为常量,我可以使它生成“快速”sql,但我希望能够在运行时更改“value”的值。有没有办法强制Entity Framework不生成“exec sp_executesql” - 样式sql,因为这显然要慢得多?

1 个答案:

答案 0 :(得分:1)

here之后,我建议SQL Server(LINQ / EF)试图超越你,并且可以告诉你将使用不同的参数重新使用该查询,并且利用sp_executesql是目前推荐的一致运行该查询的方法(非常确定它可以使SQL Server有效地缓存查询)。您可能会失去这一个查询,但是通过重复使用可以获得惩罚吗?

您可以考虑修改数据库以要求simpleforced参数化(您希望'强制'),但这可能导致任何其他查询的显着性能下降,但YMMV。< / p>

我建议避免在SQL Server本身内进行任何字符串比较......这些天RAM已经非常丰富了,而且我发现偶尔提升两个相应的数据集并比较字符串值会更快C#(再次,YMMV)

如果做不到这一点,请根据您的要求,尝试使用SOUNDEXDIFFERENCELIKECHARINDEX,了解是否可以在效果方面取得任何进展。

祝你好运。