从数据库加载大对象图。 该查询有许多Includes和Where()使用Contains()来过滤最终结果。 包含约一千个条目的集合调用包含。
分析器显示了人类难以理解的可怕SQL。 由于Contains(),无法预编译查询。
有没有办法优化此类查询?
更新
public List<Vulner> GetVulnersBySecurityObjectIds(int[] softwareIds, int[] productIds)
{
var sw = new Stopwatch();
var query = from vulner in _businessModel.DataModel.VulnerSet
join vt in _businessModel.DataModel.ObjectVulnerTieSet.Where(ovt => softwareIds.Contains(ovt.SecurityObjectId))
on vulner.Id equals vt.VulnerId
select vulner;
var result = ((ObjectQuery<Vulner>)query.OrderBy(v => v.Id).Distinct())
.Include("Descriptions")
.Include("Data")
.Include("VulnerStatuses")
.Include("GlobalIdentifiers")
.Include("ObjectVulnerTies")
.Include("Object.ProductObjectTies.Product")
.Include("VulnerComment");
//Если переданы конкретные продукты, добавляем фильтрацию
if (productIds.HasValues())
result = (ObjectQuery<Vulner>)result.Where(v => v.Object.ProductObjectTies.Any(p => productIds.Contains(p.ProductId)));
sw.Start();
var str = result.ToTraceString();
sw.Stop();
Debug.WriteLine("Сборка запроса заняла {0} секунд.", sw.Elapsed.TotalSeconds);
sw.Restart();
var list = result.ToList();
sw.Stop();
Debug.WriteLine("Получение уязвимостей заняло {0} секунд.", sw.Elapsed.TotalSeconds);
return list;
}
答案 0 :(得分:2)
几乎可以肯定的是,尽管有更多的数据包往返,但将查询分割成碎片的效果更好。始终建议限制包含的数量,因为它们不仅会破坏查询的大小和复杂性(如您所注意到的),而且还会在长度和宽度上炸毁结果集。而且,它们经常被翻译成外连接。
除此之外,使用Contains
的方式就行了。
抱歉,如果不了解您的数据模型和所涉及的表的大小,很难更具体。