【问题标题】:string.contains in LINQ to entities causes very slow executionLINQ to 实体中的 string.contains 导致执行速度非常慢
【发布时间】:2012-08-30 11:14:01
【问题描述】:

这个 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”声明为常量,我也可以让它生成“fast”sql,但我希望能够在运行时更改“value”的值。有什么方法可以强制实体框架不生成“exec sp_executesql” - 样式 sql,因为这显然要慢得多?

【问题讨论】:

  • 也许这有帮助,因为它是相关的:stackoverflow.com/questions/9270490/…
  • 可能是"parameter sniffing"的问题。
  • 我尝试了 OPTION(RECOMPILE),它使查询的执行速度提高了两倍。它仍然太慢而无法接受,因为我实际上在查询中包含了许多其他表,这加剧了问题。目前我们已经找到了解决我们问题的另一种解决方案,它不涉及“包含” - 查询。

标签: sql-server entity-framework-4


【解决方案1】:

here 开始,我建议 SQL Server (LINQ/EF) 试图超越您,并且可以告诉您,您将使用不同的参数重新使用该查询,并利用 sp_executesql是当前推荐的一致运行该查询的方法(很确定它是这样 SQL Server 可以有效地缓存查询)。您可能会输掉这一查询,但通过重复使用来弥补损失?

您可以考虑修改数据库以要求 simpleforced 参数化(您想要“强制”),但这可能会导致任何其他查询的性能显着下降,但 YMMV 除外。

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

如果做不到这一点,请根据您的要求尝试使用SOUNDEXDIFFERENCELIKECHARINDEX,看看在性能方面是否有任何提升。

祝你好运。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    相关资源
    最近更新 更多