Skip to main content
 首页 » 编程设计

c#之小型集合中 linq 和 INTERSECT/EXCEPT 的低性能

2024年02月04日27shanyou

你好吗?

我知道有很多关于它的问题和答案,但我的情况非常特殊,因为我没有大型数组可以相交。我正在实现一种搜索方法,该方法接收搜索对象并使用 linq 搜索数据库(我首先使用带有代码的 EF 6)。

  • 所以,我在数据库中有以下实体和这些列:

    -用户:userId (int), name (string).

    -UserFeatures:userId (int), featuresId (short)。

    -特征:featuresId(短),描述(字符串)。

  • 我的搜索对象是这样的:

    { "name":"弗里德里希·威廉", “特征”:[1,2,3,4]

  • 我的 linq 查询是这样的(想法是获取所有与登录用户正在寻找的功能相匹配的用户)。

    context.User.Where(u => userToSearch.features.Except(u.UserFeatures.Select(uf => uf.featuresId))).Any()==false).toListAsync();

这工作正常,但大约需要 30 秒。我在数据库中有 30k 用户,但每个用户都有大约 4 到 5 个功能。

我已经尝试使用 hashset,但由于特征集合不大,所以没有区别。问题可能是我有 30k 用户,每个用户有 5 个功能。所以这意味着大约 150k 次迭代。

你知道我该如何改进吗?在查询中我还有另一个条件。如果我删除具有这些功能的那个,查询会快得多(运行大约 4 秒。我还实现了分页 - Take、skip 等)。

请您参考如下方法:

我认为像这样使用 join 和 group by 会更快:

int numberOfFeatures = userToSearch.features.Count(); 
var userIds = from u in context.Users 
              from uf in u.UserFeatures 
              where userToSearch.features.Contains(uf.featuresId) 
              group u by u.userId into g 
              where g.Count() == numberOfFeatures  
              select u.Key; 

或者如果你想要用户对象

var users = ... 
            select u.FirstOrDefault();