如何改进此 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]
桌子上?
所以您可能有skills
、userSkills
和User
表,对吗?你不仅要索引skills
,更具体地说,要确保你的索引涵盖userSkills
啊,在 userID 上显示一个,但在 SkillID 上没有。让我试试以上是关于如何改进此 LINQ 查询以查找用户将列表中的所有技能的主要内容,如果未能解决你的问题,请参考以下文章
具有 LINQ 的实体框架在 WHERE 子句中使用 CONTAINS 非常慢且具有大整数列表
SQL Server 查询以查找数据库中所有用户的所有权限/访问权限
Linq 查询 - 根据第一个字母 b/w 两个范围查找字符串