如何改进此 LINQ 查询以查找用户将列表中的所有技能

Posted

技术标签:

【中文标题】如何改进此 LINQ 查询以查找用户将列表中的所有技能【英文标题】:How to improve this LINQ query to find users will all skills in list 【发布时间】:2017-03-01 21:48:43 【问题描述】:

我在优化此查询时遇到了一些问题。

这是为了过滤掉具有特定技能的用户。

这些技能以 ID 列表的形式发送到服务器,这些 ID 是 GUID。

不幸的是,我不能像我希望的那样简单地获取用户,因为最后一个处理此问题的人将它放在 SQL 视图中。

我们在这里尝试找到所有选择了所有技能的用户。

skillIDs 是 GUID 列表

这是它的样子

myview.Where(view => skillIDs.All(skill => view.User.Skills.Any(s => s.ID == skill)))

我们尝试过的其他事情

myView.Where(view => !skillIDs.Except(view.User.Skills.Select(skill => skill.ID).Any()))

myview.Where(view => skillIDs.All(skill => view.User.Skills.Select(s => s.ID).contains(skill)))

我意识到它的工作方式非常低效,是的,我们正在对结果进行分页,但直到此查询之后。我相信正在发生的是它在这里执行查询,而不是等待应该执行的.skip(0).Take(10).tolist()。现在它需要 45 秒才能工作。当它不尝试执行上面的查询时不到一秒,所以我知道这是罪魁祸首。

【问题讨论】:

你的列有索引吗? 我有,但是你不能真正在sql视图上做索引 为什么视图上没有索引? 但是您试图让所有拥有一套技能的用户都正确吗? skillIDs 通常包含多少个元素? 【参考方案1】:

在这种情况下,使用不同的 LINQ 变体不会产生影响,因为问题可能出在后端表索引上,而不是您如何创建 LINQ 语句。你真的有两个选择:

    索引后端表,因为视图可以在需要时使用表上的索引

    直接索引视图。索引视图的定义必须是确定性的。 MSDN

    创建唯一的聚集索引 IDX_V1 ON myview (skillid); 去吧

【讨论】:

问题是技能ID在视图中不存在,必须通过导航项抓取,所以它不完全是可以索引的东西 SkillID 在技能表中被索引 我根据您的 LINQ 查询怀疑它;在这种情况下,您仍然有选项 #1 正在创建索引。如果没有数据库模式,很难准确地说出它需要在哪里。我猜可能在[Skills] 桌子上? 所以您可能有skillsuserSkillsUser 表,对吗?你不仅要索引skills,更具体地说,要确保你的索引涵盖userSkills 啊,在 userID 上显示一个,但在 SkillID 上没有。让我试试

以上是关于如何改进此 LINQ 查询以查找用户将列表中的所有技能的主要内容,如果未能解决你的问题,请参考以下文章

使用经度和纬度查找给定距离内的所有附近客户

具有 LINQ 的实体框架在 WHERE 子句中使用 CONTAINS 非常慢且具有大整数列表

SQL Server 查询以查找数据库中所有用户的所有权限/访问权限

Linq 查询 - 根据第一个字母 b/w 两个范围查找字符串

c# 在 LINQ 查询返回的列表中查找项目并将其值与列表中的另一个项目进行比较

Linq 到实体 Skip() 和 Take()