我正在使用Linq实体来查询数据库以获取int列表以供进一步处理。我有两种方法可以获得如下列表:
首先是:
List<int> lstBizIds = new List<int>() { 1, 2, 3, 4, 5 };
List<int> lstProjectIds = context.Projects.Where(x => lstBizIds.Contains(x.businessId)).Select(x => x.projectId).ToList();
第二是:
List<int> lstBizIds = new List<int>() { 1, 2, 3, 4, 5 };
List<int> lstProjectIds = context.Projects.Join(lstBizIds, p => p.businessId, u => u, (p, u) => p.projectId).ToList();
现在我的问题是上面哪种方法的性能更好?如果第一个列表,即lstBizIds的大小增加,它是否也会影响性能?如果性能降低,建议我采用其他实施方式。
答案 0 :(得分:4)
你应该使用Contains
,因为EF可以产生更有效的查询。
这将是SQL连接:
SELECT Id
FROM Projects
INNER JOIN (VALUES (1), (2), (3), (4), (5)) AS Data(Item) ON Projects.UserId = Data.Item
这将是SQL Contains:
SELECT Id
FROM Projects
WHERE UserId IN (1, 2, 3, 4, 5, 6)
IN
比JOIN
效率更高,因为DBMS可以停止查看IN
的第一个匹配项; JOIN
总是在第一场比赛结束后结束。
您可能还想检查哪些查询实际发送到数据库。你总是需要比较SQL,而不是LINQ代码(显然)。
答案 1 :(得分:1)
执行连接非常有效,因为Where条件实际上执行了所有表的笛卡尔积,然后过滤满足条件的行。这意味着为每个行组合(n1 * n2 * n3 * n4)
评估Where条件Join运算符从第一个表中获取行,然后仅获取第二个表中具有匹配键的行,然后仅获取第三个表中具有匹配键的行,依此类推。其次,contains会以迭代的方式工作,使其比join
慢答案 2 :(得分:0)
我选择第一个,因为它不会增加计算机的内存
如果您使用两个数组来比较条件,请从第二个选择。
答案 3 :(得分:0)
我花了很长时间试图找到一个程序中出现堆栈溢出错误的原因,其中一些简单的LINQ查询访问了一个中等大小的数据库。
对于ICollection的,一边是~10k元素,另一边是sql表,从“join”到“Contains”的单一更改修复了堆栈溢出错误。
似乎尽管有比较性能,但Contains是一个更安全的选择。