关于性能:为什么Contains()运算符会降低Entity Framework的Linq查询?

Why does the Contains() operator degrade Entity Framework' Linq queries?

我在这里阅读到,在实体框架中,如果您执行包含操作,则会降低性能:

Contains is converted to"WHERE IN" in SQL which cause performance degrades"

现在,我有近10个表,其中有10列,而在获取记录时,我使用Contains包含了近8列。

我的问题是真的吗? 如果是,那还有什么替代方法?


是Contains()将严重降低性能。

因此,您可以尝试以下提到的解决方案。

通过添加中间表并通过需要使用Contains子句的LINQ查询将该表连接到表上,我们能够解决EF Contains问题。通过这种方法,我们能够获得惊人的结果。我们拥有大型的EF模型,并且由于在预编译EF查询时不允许使用"包含",因此对于使用"包含"子句的查询而言,性能会变得很差。

概述:

  • 在SQL Server中创建一个表-例如,具有Guid数据类型的HelperID和int数据类型列的ReferenceID的HelperForContainsOfIntType。根据需要使用具有不同数据类型的ReferenceID创建不同的表。

  • 在EF模型中为HelperForContainsOfIntType和其他此类表创建一个Entity / EntitySet。根据需要为不同的数据类型创建不同的Entity / EntitySet。

  • 在.NET代码中创建一个辅助方法,该方法接受IEnumerable的输入并返回Guid。此方法生成一个新的Guid,并将IEnumerable中的值与生成的Guid一起插入HelperForContainsOfIntType。接下来,该方法将此新生成的Guid返回给调用方。为了快速插入HelperForContainsOfIntType表,请创建一个存储过程,该过程将输入值列表并进行插入。请参阅SQL Server 2008(ADO.NET)中的表值参数。为不同的数据类型创建不同的帮助程序,或创建通用的帮助程序方法以处理不同的数据类型。

  • 创建一个类似于以下内容的EF编译查询:

    1
    2
    3
    4
    5
    6
    7
    static Func<MyEntities, Guid, IEnumerable<Customer>> _selectCustomers =
        CompiledQuery.Compile(
            (MyEntities db, Guid containsHelperID) =>
                from cust in db.Customers
                join x in db.HelperForContainsOfIntType on cust.CustomerID equals x.ReferenceID where x.HelperID == containsHelperID
                select cust
        );

    使用在Contains子句中使用的值来调用helper方法,并获取要在查询中使用的Guid。例如:

    1
    2
    var containsHelperID = dbHelper.InsertIntoHelperForContainsOfIntType(new int[] { 1, 2, 3 });
    var result = _selectCustomers(_dbContext, containsHelperID).ToList();

    我从这里得到的