programing

엔티티 프레임워크는 매 컴파일 후 처음 로드되는 속도가 매우 느림

cafebook 2023. 9. 15. 21:19
반응형

엔티티 프레임워크는 매 컴파일 후 처음 로드되는 속도가 매우 느림

제목에서 알 수 있듯이 Entity Framework를 사용하는 SQL Server 데이터베이스에 대한 첫 번째 쿼리에 문제가 있습니다.답을 찾으려고 노력했지만 아무도 이에 대한 해결책을 가지고 있지 않은 것 같습니다.

테스트는 Entity Framework 6을 사용하여 Visual Studio 2012에서 수행되었으며, T4 뷰 템플릿을 사용하여 뷰를 사전 컴파일했습니다.데이터베이스는 SQL Server 2008에 있었습니다.우리는 약 400개의 POC(400개의 매핑 파일)를 가지고 있고, 데이터베이스 테이블에는 100개의 행 데이터만 있습니다.

다음 캡쳐는 저의 테스트 코드와 결과입니다.

static void Main(string[] args){
    Stopwatch st=new Stopwatch();
    st.Start();
    new TestDbContext().Set<Table1>.FirstOrDefault();
    st.stop();
    Console.WriteLine("First Time "+st.ElapsedMilliseconds+ " milliseconds");

    st.Reset();
    st.Start();
    new TestDbContext().Set<Table1>.FirstOrDefault();
    st.stop();
    Console.WriteLine("Second Time "+st.ElapsedMilliseconds+ " milliseconds");
}

시험결과

First Time 15480 milliseconds
Second Time 10 milliseconds

첫 번째 쿼리에서 EF는 모델을 컴파일합니다.이 정도 크기의 모델의 경우 심각한 시간이 소요될 수 있습니다.

다음은 세 가지 제안입니다: http://www.fusonic.net/en/blog/2014/07/09/three-steps-for-fast-entityframework-6.1-first-query-performance/

요약:

  1. 캐시된 DB 모델 저장소 사용
  2. 미리 컴파일된 보기 생성
  3. n-gen을 사용하여 미리 컴파일된 버전의 엔티티 프레임워크를 생성하여 jiting을 방지합니다.

벤치마크를 할 때는 릴리즈 모드로 어플리케이션을 컴파일하도록 하겠습니다.

또 다른 해결책은 DBC 컨텍스트를 분할하는 것을 고려하는 것입니다.400개의 개체는 많고 더 작은 덩어리로 작업하는 것이 더 좋을 것입니다.시도해 본 적은 없지만 한 번의 부하도 15초가 걸리지 않는다는 의미로 하나씩 모델을 제작하는 것이 가능할 것 같습니다.Julie Lerman의 이 게시물 보기 https://msdn.microsoft.com/en-us/magazine/jj883952.aspx

EF Core를 사용하면 전화 후에 모델을 속이고 일찍 로드할 수 있습니다.services.AddDbContext(당신도 아마 EF6와 비슷한 작업을 할 수 있겠지만, 테스트해 본 적은 없습니다.)

services.AddDbContext<MyDbContext>(options => ...);
var options = services.BuildServiceProvider()
                      .GetRequiredService<DbContextOptions<MyDbContext>>();
Task.Run(() =>
{
    using(var dbContext = new MyDbContext(options))
    {
        var model = dbContext.Model; //force the model creation
    }
});

이렇게 하면 응용프로그램의 나머지 초기화(및 다른 준비 작업)가 완료되고 요청이 시작되는 동안 다른 스레드에 dbcontext 모델이 생성됩니다.이렇게 하면 더 빨리 준비될 겁니다.필요할 때 EFcore는 아직 모델이 완성되지 않았다면 모델이 생성되기를 기다릴 것입니다.Model모든 DbContext 인스턴스 간에 공유되므로 이 더미 dbcontext를 실행하고 잊어버려도 좋습니다.

이와 같은 시도를 해볼 수 있습니다: (저에게는 효과가 있었습니다.)

protected void Application_Start()
{

    Start(() =>
    {
        using (EF.DMEntities context = new EF.DMEntities())
        {
            context.DMUsers.FirstOrDefault();
        }
    });
}
private void Start(Action a)
{
    a.BeginInvoke(null, null);
} 

엔티티 프레임워크 - 첫번째 쿼리 속도가 느림

나를 위한 이 일:

using (MyEntities db = new MyEntities())                
{
   db.Configuration.AutoDetectChangesEnabled = false; // <----- trick
   db.Configuration.LazyLoadingEnabled = false; // <----- trick

   DateTime Created = DateTime.Now;

   var obj = from tbl in db.MyTable
      where DateTime.Compare(tbl.Created, Created) == 0
      select tbl;

   dataGrid1.ItemsSource = obj.ToList();
   dataGrid.Items.Refresh();
}

c#에서 사용되지 않는 테이블이 많을 경우 제외합니다.

부분 클래스를 추가하고 다음 코드를 추가하며 OnModelCreating에서 이 기능을 참조합니다.

void ExcludedTables(DbModelBuilder modelBuilder)
{
    modelBuilder.Ignore<Table1>();
    modelBuilder.Ignore<Table>();
   // And so on
}

저는 첫 번째 쿼리에서 As Parallel()을 사용하는 것만으로도 문제가 해결되었습니다.이것은 여러 프로세서 코어에서 쿼리를 실행합니다(분명히).이후의 모든 문의는 변경되지 않았으며, 지연의 원인이 된 첫 번째 문의일 뿐입니다.

도 미리 생성된 매핑 뷰 https://learn.microsoft.com/en-us/ef/ef6/fundamentals/performance/pre-generated-views 를 시도해 보았지만, 이것은 시작 시간을 크게 향상시키지 못했습니다.

저는 그것이 매우 좋은 해결책이 아니라고 생각합니다.Ado.net 은 훨씬 더 성능이 좋아 보입니다.하지만 이것은 제 의견입니다.

다른 방법으로 봐요.

https://msdn.microsoft.com/tr-tr/data/dn582034

https://msdn.microsoft.com/en-us/library/cc853327(v=vs.100).aspx

언급URL : https://stackoverflow.com/questions/30423838/entity-framework-very-slow-to-load-for-first-time-after-every-compilation

반응형