SQL Server Union与SELECT TOP(x)优化

时间:2016-02-05 12:26:23

标签: sql-server entity-framework optimization union

我最近处理了一个调用,其中运行的查询(通过实体框架)超时。这是由另一位开发人员编写的代码执行了以下操作。

创建了一组复杂的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服务器中运行查询以调查执行计划:

enter image description here

我发现一件奇怪的事情是,当不选择前100条记录时,查询速度要快得多(如上所示)。右侧查询的执行计划显示延迟是由工会引起的:

enter image description here

我发现这很奇怪,因为两个查询都有联盟。唯一的区别是TOP(100),但我采取措施通过从等式中删除联合来修复问题。我通过保持2 IQueryable分开,将过滤器应用于两者,然后执行它们并将它们连接在内存中来实现这一点。这大大减少了搜索最终用户的总体执行时间。

现在,我必须填写不合规文书作为组织的要求。我不太清楚该怎么说:

  

防止将来出现不合规的行动

部分,因为我不完全确定问题的根本原因是什么。我不愿意说:不要使用SQL联盟,因为它本身并不是我问题的原因。

0 个答案:

没有答案