Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 在使用字段构建EF查询方面存在巨大的性能差异_Entity Framework - Fatal编程技术网

Entity framework 在使用字段构建EF查询方面存在巨大的性能差异

Entity framework 在使用字段构建EF查询方面存在巨大的性能差异,entity-framework,Entity Framework,通过使用字段构建查询,我注意到了一些巨大的性能差异。例如: 带有字段的性能:数据库读取数:21118,持续时间:156 无字段的性能:数据库读取数:8113,持续时间:29 带有字段的代码示例 var newStatus = OrderStatus.New.ToString(); var inProgressStatus = OrderStatus.InProgress.ToString(); var inReview = OrderStatus.InReview.ToString(); v

通过使用字段构建查询,我注意到了一些巨大的性能差异。例如:

带有
字段的性能:数据库读取数:21118,持续时间:156

无字段的性能:数据库读取数:8113,持续时间:29


带有字段的代码示例

var newStatus = OrderStatus.New.ToString();
var inProgressStatus = OrderStatus.InProgress.ToString();
var inReview = OrderStatus.InReview.ToString();

var data = ctx.COM_Order
  .Select(o => new QueryModel
  {
      Order = o,
      SortPrio = (o.COM_OrderStatus.StatusName == newStatus
      || o.COM_OrderStatus.StatusName == inProgressStatus
      || o.COM_OrderStatus.StatusName == inReview
      ? 1 : 2),

      ClassNames = o.COM_OrderItem
          .Join(CMS_Tree, orderItem => orderItem.OrderItemSKUID, tree => tree.NodeSKUID,
          (oi, t) => t.CMS_Class.ClassName),

        UDM_LegalData = UDM_LegalData.Where(d => o.COM_Customer.CustomerID == d.CustomerID).FirstOrDefault(),
        UDM_OrderStatusHistory = UDM_OrderStatusHistory.Where(h => h.OrderId == o.OrderID),
  });
var data = ctx.COM_Order
.Select(o => new QueryModel
{
    Order = o,
    SortPrio = (o.COM_OrderStatus.StatusName == "New"
    || o.COM_OrderStatus.StatusName == "InProgress"
    || o.COM_OrderStatus.StatusName == "InReview"
    ? 1 : 2),

    ClassNames = o.COM_OrderItem
        .Join(CMS_Tree, orderItem => orderItem.OrderItemSKUID, tree => tree.NodeSKUID,
        (oi, t) => t.CMS_Class.ClassName),

        UDM_LegalData = UDM_LegalData.Where(d => o.COM_Customer.CustomerID == d.CustomerID).FirstOrDefault(),
        UDM_OrderStatusHistory = UDM_OrderStatusHistory.Where(h => h.OrderId == o.OrderID),
});
SQL输出:

不带字段的代码示例

var newStatus = OrderStatus.New.ToString();
var inProgressStatus = OrderStatus.InProgress.ToString();
var inReview = OrderStatus.InReview.ToString();

var data = ctx.COM_Order
  .Select(o => new QueryModel
  {
      Order = o,
      SortPrio = (o.COM_OrderStatus.StatusName == newStatus
      || o.COM_OrderStatus.StatusName == inProgressStatus
      || o.COM_OrderStatus.StatusName == inReview
      ? 1 : 2),

      ClassNames = o.COM_OrderItem
          .Join(CMS_Tree, orderItem => orderItem.OrderItemSKUID, tree => tree.NodeSKUID,
          (oi, t) => t.CMS_Class.ClassName),

        UDM_LegalData = UDM_LegalData.Where(d => o.COM_Customer.CustomerID == d.CustomerID).FirstOrDefault(),
        UDM_OrderStatusHistory = UDM_OrderStatusHistory.Where(h => h.OrderId == o.OrderID),
  });
var data = ctx.COM_Order
.Select(o => new QueryModel
{
    Order = o,
    SortPrio = (o.COM_OrderStatus.StatusName == "New"
    || o.COM_OrderStatus.StatusName == "InProgress"
    || o.COM_OrderStatus.StatusName == "InReview"
    ? 1 : 2),

    ClassNames = o.COM_OrderItem
        .Join(CMS_Tree, orderItem => orderItem.OrderItemSKUID, tree => tree.NodeSKUID,
        (oi, t) => t.CMS_Class.ClassName),

        UDM_LegalData = UDM_LegalData.Where(d => o.COM_Customer.CustomerID == d.CustomerID).FirstOrDefault(),
        UDM_OrderStatusHistory = UDM_OrderStatusHistory.Where(h => h.OrderId == o.OrderID),
});
SQL输出:

为什么会有如此巨大的性能差异?我可以使用没有性能缺陷的字段/枚举吗

谢谢

  • 使用EF版本6.0.2和6.1.3进行测试

更新1

  • 添加了sql输出
  • 将示例查询更新为“完整EF查询”(我无法再现与降级示例查询的性能差异)
更新2

  • 添加了EF版本信息
为什么会有如此巨大的性能差异

关于第三方组件的实现为什么或为什么不实现的问题总是很难用“因为”来回答

显然,当涉及变量时,SQL生成的方向与涉及值时不同。我不知道为什么,我也不会猜

我所知道的是,您可以通过使用
Contains
,强制生成更好的查询形状:

var statuses = new[] { newStatus, inProgressStatus, inReview };
var data = ctx.COM_Order
  .Select(o => new QueryModel
  {
      Order = o,
      SortPrio = statusses.Contains(o.COM_OrderStatus.StatusName) ? 1 : 2),
      ...

这将始终转换为语句中的

您是否查看了生成的SQL以了解它们之间的差异?我怀疑您是否在编译和运行查询时第一次检查它们。当然,第一个查询需要更多的步骤来构建场景后面的表达式树,所以构建表达式树只是时间上的差异。您可以在第一次运行后尝试测试它。由于EF 5,查询是缓存的,所以从第二次运行开始,就不会有构建表达式树的步骤了?SQL Server是否读取(从探查器)?您能否发送整个型号(至少包括COM_订单、订单状态和控制器)?我想调查以了解这种行为,因为在这种情况下,表达式树应该非常相似,查询应该是相同的。这是哪个EF版本?从第一次生成的查询中,当(([Extent2].[StatusName]=@p_ulinq_u0)和([Extent2].[StatusName]为NULL或@p_ulinq_u0为NULL))或([Extent2][StatusName]为NULL)和(@p_uLinq_u0为NULL))或([Extent2].[StatusName]=@p_uLinq_u1)和([Extent2].[StatusName]为NULL或@p_uLinq_u1为NULL))或([Extent2].[StatusName]为NULL)和(@p_uLinq_u1为NULL))或([Extent2].[StatusName]=@p_uLinq_u2]或[Extent2]为NULL][StatusName]为NULL)和(@p_uulinq_uu2为NULL)),然后1或2结束为[C1]
…Hi Gert,使用“Contains”EF生成快速查询。美好的而你的其他话正好切中要害;)谢谢