Asp.net core mvc EF7在Include()上的性能缓慢

Asp.net core mvc EF7在Include()上的性能缓慢,asp.net-core-mvc,entity-framework-core,Asp.net Core Mvc,Entity Framework Core,我正在调查应用程序的缓慢性能(Azure上的页面加载时间超过8秒),发现了一件有趣的事情 以下代码执行大约需要0.318秒 var reservations = db.Reservations.Include(r => r.PickUpLocation); var reservationsList = reservations.ToList(); 但是如果我手动加载导航属性,它的完成速度将提高2.5倍(0.128秒) 对于更复杂的查询,差异甚至更大——高达

我正在调查应用程序的缓慢性能(Azure上的页面加载时间超过8秒),发现了一件有趣的事情

以下代码执行大约需要0.318秒

        var reservations = db.Reservations.Include(r => r.PickUpLocation);
        var reservationsList = reservations.ToList();
但是如果我手动加载导航属性,它的完成速度将提高2.5倍(0.128秒)

对于更复杂的查询,差异甚至更大——高达20倍(例如8秒对0.8秒)

我尝试了QueryTrackingBehavior.NoTracking和QueryTrackingBehavior.TrackAll,但对性能没有显著影响

我还注意到LiveAzure比本地机器慢10倍,并且在EF/手动方法之间显示出更高的性能差异

有没有办法让EF工作得更快

更新: 位置表有121行(6个字符串列,1个布尔值和2个int值) 预订表有1268行

预订模型类的重要部分:

public class Reservation
{
    public int ID { get; set; }

    ...

    [ForeignKey("PickUpLocation")]
    public int PickUpLocationID { get; set; }
    public Location PickUpLocation { get; set; }

    ...
}
public class Location
{
    public int ID { get; set; }

    [StringLength(100)]
    public string Name { get; set; }

    [StringLength(255)]
    public string Address { get; set; }

    [StringLength(25)]
    public string Barangay { get; set; }

    [StringLength(25)]
    public string City { get; set; }

    [StringLength(25)]
    public string Province { get; set; }

    [StringLength(20)]
    public string Country { get; set; }

    [Display(Name = "Service Type")]
    public LocationServiceType? ServiceType { get; set; }

    [Display(Name = "Location Type")]
    [Required]
    public LocationType? LocationType { get; set; }

    public bool IsDeleted { get; set; }
}
位置模型类:

public class Reservation
{
    public int ID { get; set; }

    ...

    [ForeignKey("PickUpLocation")]
    public int PickUpLocationID { get; set; }
    public Location PickUpLocation { get; set; }

    ...
}
public class Location
{
    public int ID { get; set; }

    [StringLength(100)]
    public string Name { get; set; }

    [StringLength(255)]
    public string Address { get; set; }

    [StringLength(25)]
    public string Barangay { get; set; }

    [StringLength(25)]
    public string City { get; set; }

    [StringLength(25)]
    public string Province { get; set; }

    [StringLength(20)]
    public string Country { get; set; }

    [Display(Name = "Service Type")]
    public LocationServiceType? ServiceType { get; set; }

    [Display(Name = "Location Type")]
    [Required]
    public LocationType? LocationType { get; set; }

    public bool IsDeleted { get; set; }
}
在详细登录的情况下执行应用程序时,我可以看到实际执行的SQL查询。EF7只执行一个查询:

  Executed DbCommand (5ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
  SELECT [r].[ID], [r].[AssignedUnitID], [r].[AssignedUnitThirdParty], [r].[BookingCode], [r].[Comments], [r].[DailyPriceID], [r].[DamageDescription], [r].[DocumentCountry], [r].[DocumentNumber], [r].[DocumentOwnerName], [r].[DocumentType], [r].[Email], [r].[FirstName], [r].[FlightArrival], [r].[FlightNumber], [r].[HomeAddress], [r].[LastName], [r].[Phone], [r].[PickUpDateTime], [r].[PickUpLocationID], [r].[RequestedVehicleModelID], [r].[RequestedVehicleTypeID], [r].[ReturnDateTime], [r].[ReturnLocationID], [r].[State], [r].[StayingAddress], [r].[ThirdPartyName], [r].[Type], [r].[UserId], [r].[VersionDate], [l].[ID], [l].[Address], [l].[Barangay], [l].[City], [l].[Country], [l].[IsDeleted], [l].[LocationType], [l].[Name], [l].[Province], [l].[ServiceType]
  FROM [Reservation] AS [r]
  INNER JOIN [Location] AS [l] ON [r].[PickUpLocationID] = [l].[ID]

因此,问题一定在于它如何解析结果。

您是否验证了
将包含多少额外数据。在您的案例中包含
?我个人更喜欢用内部联接压缩显式SELECT语句,只填充我真正需要的字段。我认为你可以独立于Azure来分析这个问题。您发布的代码没有包含有关模型的足够详细信息。不能定义在这两种情况下将生成哪些SQL语句。此外,EF7可能有一些bug,您只能通过检查生成的SQL selects.Oleg来设置这些bug。我更新了问题,以包含由EF7生成的SQL查询的模型类。该查询看起来还可以。我看不出8秒甚至0.8秒的理由。应该快得多。您是否验证了
ID
确实是主键?我个人使用EF而不使用EF(请参阅with direct SQL语句)。我没有看到你的代码中有错误。本地数据库是否存在相同的性能问题?我建议你在本地数据库中分析这个问题。您可以使用SQL Server 2014探查器来检查哪一部分花费了8秒钟。也许你也可以在Azure上使用探查器。8秒用于更复杂的查询。为了性能研究,我简化了它。简化查询(来自post)需要0.318秒(比手动查询慢2.5倍)。本地数据库也有同样的问题。SQL本身似乎表现良好(查询为4毫秒),因此问题应该在EF本身的某个地方。我也有同样的问题,在我的例子中,发送到SQL Server的T-SQL,如果在SQL Server Management Studio中运行,需要3秒钟。如果使用EF7运行查询,如果使用包含的原始sql,则需要5分钟。