我最近处理了一个调用,其中运行的查询(通过实体框架)超时。这是由另一位开发人员编写的代码执行了以下操作。
创建了一组复杂的2 IQueryable
,然后与Union
一起加入:
IQueryable<AwardListing> listData = null;
listData = GetGoodsAwards();
listData = listData.Union(GetServicesAwards());
接下来,根据用户的输入将一组过滤器应用于生成的IQueryable
,并应用于不同的列:
if (!string.IsNullOrEmpty(ReferenceNumberOrKeyword))
{
Expression<Func<AwardListing, bool>> referenceOrKeywordFilter = r => r.ReferenceNumber.ToLower().Contains(ReferenceNumberOrKeyword.ToLower())
|| r.Title.ToLower().Contains(ReferenceNumberOrKeyword.ToLower());
listData = listData.Where(referenceOrKeywordFilter);
}
// more filters applied etc.
最后,返回前100条记录,因为完整集合通常包含太多记录传递给客户端:
return listData.Take(100).ToList<AwardListing>();
我在SQL服务器中运行查询以调查执行计划:
我发现一件奇怪的事情是,当不选择前100条记录时,查询速度要快得多(如上所示)。右侧查询的执行计划显示延迟是由工会引起的:
我发现这很奇怪,因为两个查询都有联盟。唯一的区别是TOP(100)
,但我采取措施通过从等式中删除联合来修复问题。我通过保持2 IQueryable
分开,将过滤器应用于两者,然后执行它们并将它们连接在内存中来实现这一点。这大大减少了搜索最终用户的总体执行时间。
现在,我必须填写不合规文书作为组织的要求。我不太清楚该怎么说:
防止将来出现不合规的行动
部分,因为我不完全确定问题的根本原因是什么。我不愿意说:不要使用SQL联盟,因为它本身并不是我问题的原因。