【问题标题】:What are the ways to optimize Entity Framework queries with Contains()?使用 Contains() 优化实体框架查询的方法有哪些?
【发布时间】:2012-10-22 11:32:42
【问题描述】:

我们从数据库加载大对象图。 查询有很多 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;
        }

【问题讨论】:

  • 也许,但不是没有看到你正在尝试做的例子......
  • 仅限明天。代码留在办公室 =)
  • 我认为 contains 使用 like '%%' 应该可以通过全文索引 sql 中的列来调整
  • 提高Contains 性能的解决方案是将softwareIds 集合拆分为更小的块并执行多个查询:stackoverflow.com/a/7936350/270591

标签: entity-framework


【解决方案1】:

几乎可以肯定,将查询拆分为多个片段会更好,尽管有更多的 db 往返。始终建议限制包含的数量,因为它们不仅会放大查询的大小和复杂性(正如您所注意到的),还会在长度和宽度上放大结果集。此外,它们经常被翻译成外连接。

除此之外,使用Contains 就可以了。

抱歉,如果不知道您的数据模型和所涉及的表的大小,很难更具体。

【讨论】:

  • 好文章!关于我们的问题的重要引用:“一旦您在查询中包含三个或更多实体,请考虑切换到延迟加载。”并且“其中包含多个包含语句的查询需要相对较长的时间才能通过我们的内部计划编译器”。并且“这样的查询将在单个有效负载中从您的数据库中引入大型连接图,这将加剧任何带宽问题”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多