지연 로딩 vs Eager 로딩


79

Entity Framework의 지연로드는 관련 엔터티를로드하고 액세스 할 때 발생하는 기본 현상입니다. 그러나 eager loading은 이러한 모든 관계에 힘을 가하는 관행을 말합니다. 나는 어떤 상황에서 eager loading이 lazy loading보다 더 유익 할 수 있는지에 대한 질문을 보았습니다. 이것에 대해 물어 보면, 지연 로딩이 더 자원 친화적 인 것이 분명하고 ToList(), 우리가 방법 을 사용하더라도 지연 로딩 동작을 여전히 이용할 수 있기 때문입니다. 그러나 지연로드가 실제 데이터베이스에 대한 요청 수를 증가시킬 수 있다고 생각했고, 이것이 개발자가Inlcude 모든 관계를 강제로로드 방법을 . 예를 들어 MVC 5에서 Visual Studio 자동 스캐 폴딩을 사용할 때 컨트롤러에서 자동으로 생성되는 Index 메서드는 항상 Eager Loading을 사용하며,이 경우 Microsoft가 기본적으로 Eager Loading을 사용하는 이유에 대한 질문이 항상있었습니다.

누군가가 지연 로딩보다 eager loading이 어떤 상황에서 더 유익한 지, 왜 Lazy Loading과 같은 리소스 친화적 인 것이 있는데 왜 그것을 사용하는지 설명해 주시면 감사하겠습니다.


8
DB 컨텍스트가 삭제되고 더 이상 지연로드가 발생할 수없는 상황을 상상해보십시오. 그러면 즉시로드하는 것이 도움이됩니다.
Transcendent

2
지연로드를 수행 할 때 더 빨리 발생하는 "N + 1 Select"문제로 인해 성능 문제로 인해 많은 프로젝트가 실패하는 것을 보았습니다. 확인하십시오
David DV

답변:


80

이렇게 관계를 분류하면 좋을 것 같아요

즉시 로딩을 사용하는 경우

  1. 일대 다 관계의 "일면"에서 당신은 확실히 주요 엔티티와 함께 ​​모든 곳에서 사용됩니다. 기사의 사용자 속성과 같습니다. 제품의 범주 속성입니다.
  2. 일반적으로 관계가 너무 많지 않고 eager loading이 서버에서 추가 쿼리를 줄이는 데 좋은 습관이 될 때.

지연 로딩을 사용하는 경우

  1. 일대 다 관계의 거의 모든 "수집 측면"에 있습니다. 사용자 기사 또는 카테고리 제품
  2. 즉시 재산이 필요하지 않다는 것을 정확히 알고 있습니다.

참고 : Transcendent가 말한 것처럼 지연 로딩에 폐기 문제가있을 수 있습니다.


5
나는 똑같은 대답을하려고 한 것이 아니었다. 관련 데이터를 거의 사용할 필요가 없다는 것을 알고있는 경우 지연로드를 사용하십시오. 그러나 특정 관련 데이터가 자주 필요하다는 것을 알고 있으면 즉시로드를 사용하십시오.
Ghasan

두 가지를 함께 사용할 수 있습니까? 예를 들어 엔티티가 다른 엔티티와 거의 관련이있는 경우 eager loading을 통해 포함 할 수 있고 다른 관련 엔티티는 lazy loading을 통해 사용할 수 있습니까?
Ahmad Alaa

28

Eager Loading : Eager Loading은 필요한 모든 엔티티를 한 번에로드하는 데 도움이됩니다. 즉 관련 개체 (하위 개체)는 상위 개체와 함께 자동으로로드됩니다.

사용시기 :

  1. 관계가 너무 많지 않은 경우 Eager Loading을 사용합니다. 따라서 Eager Loading은 서버에서 추가 쿼리를 줄이는 좋은 방법입니다.
  2. 모든 곳에서 주요 엔터티와 함께 ​​관련 엔터티를 사용할 것이 확실한 경우 Eager Loading을 사용합니다.

지연로드 : 지연로드의 경우 관련 개체 (하위 개체)는 요청 될 때까지 부모 개체와 함께 자동으로로드되지 않습니다. 기본적으로 LINQ는 지연로드를 지원합니다.

사용시기 :

  1. 일대 다 컬렉션을 사용하는 경우 지연로드를 사용합니다.
  2. 관련 엔터티를 즉시 사용하지 않는 것이 확실한 경우 지연로드를 사용하십시오.

참고 : Entity Framework는 즉시로드, 지연로드 및 명시 적로드의 세 가지 관련 데이터로드 방법을 지원합니다.


나는 열망하고 게으른 로딩에 대해 정말로 혼란스러워합니다. 제발 이해해 주시겠습니까? Google을 참조하여 지연 로딩에 대해이 문제를 더럽 혔습니다. "지연 로딩으로 데이터를로드하려면 가상 키워드를 사용해야합니다. 지연로드는 엔티티 또는 엔티티 모음이 처음 액세스 될 때 데이터베이스에서 자동으로로드되는 프로세스입니다. 2016 년 1 월 7 일"은 지연 로딩에 대해 말씀하신 것과 동일합니다.
rykamol

@rykamol 그것을 디자인 패턴으로 이해하려고 노력하십시오. 당신은 더 나은 이해를 위해 여기에서 참조 할 수 있습니다 열망로드 - entityframeworktutorial.net/... , 게으른로드 - entityframeworktutorial.net/... , 명시로드 - entityframeworktutorial.net/EntityFramework4.3/...
암흑 물질

20

지연로드는 여러 SQL 호출을 생성하는 반면 Eager로드는 하나의 "더 무거운"호출 (조인 / 서브 쿼리 포함)으로 데이터를로드 할 수 있습니다.

예를 들어, 웹 서버와 SQL 서버간에 높은 핑이있는 경우 지연로드로 관련 항목을 1x1로로드하는 대신 Eager로드를 사용합니다.


두 가지를 함께 사용할 수 있습니까? 예를 들어 엔티티가 다른 엔티티와 거의 관련이있는 경우 eager loading을 통해 포함 할 수 있고 다른 관련 엔티티는 lazy loading을 통해 사용할 수 있습니까?
Ahmad Alaa

12

아래 상황을 고려하십시오

public class Person{
    public String Name{get; set;}
    public String Email {get; set;}
    public virtual Employer employer {get; set;}
}

public List<EF.Person> GetPerson(){
    using(EF.DbEntities db = new EF.DbEntities()){
       return db.Person.ToList();
    }
}

이제이 메서드가 호출 된 후에는 Employer더 이상 엔터티를 지연로드 할 수 없습니다 . 왜? db객체가 폐기 되었기 때문 입니다. 그래서 Person.Include(x=> x.employer)그것을 강제로로드해야합니다.


3
예, Lazy Loading이 도움이되지 않는 예입니다. 또 다른 한 가지는 데이터가 필요할 때마다 DbContext를 만드는 것이 나쁜 방법이라는 것입니다. IoC 컨테이너가 있으면 DbContext가 Request (웹 앱의 경우)와 함께 유지됩니다.
Miroslav Holec 2015

@MiroslavHolec : 훌륭합니다. 제가 실제로 Ninject를 사용하여하는 일입니다. 당신이 방금 언급 한 것은 참으로 매우 좋습니다.
Transcendent

8

Eager Loading 한 번에 여러 엔터티를 가져 오려는 경우 (예 : 동일한 페이지에 사용자 및 사용자 세부 정보를 표시해야하는 경우) 즉시로드를 사용해야합니다. 빠른로드는 데이터베이스에서 단일 히트를 만들고 관련 엔티티를로드합니다.

지연 로딩 페이지에서만 사용자를 표시해야하고 사용자를 클릭하여 사용자 세부 사항을 표시해야하는 경우 지연 로딩을 사용해야합니다. 지연로드는 관련 항목을 바인딩 / 반복 할 때 관련 항목을로드하기 위해 여러 히트를 만듭니다.


3

Lazy loading-페이지로드를 처리 할 때 10 명의 사용자가 포함 된 사용자 목록이 표시되고 사용자가 페이지를 아래로 스크롤하면 api 호출이 다음 10 명의 사용자를 불러옵니다. 더 많은 시간이 걸리고 나쁜 사용자 경험을 제공하기 때문에 한 번.

Eager loading- 데이터베이스에 대한 단일 호출로 한 번에 전체 데이터를 가져오고 관계가 많지 않을 때 다른 사람들이 제안한 것처럼 좋습니다.


-1

애플리케이션의 성능을 최적화하기 때문에 가능하면 즉시로드를 사용하는 것이 좋습니다.

전의-:

Eager loading

var customers= _context.customers.Include(c=> c.membershipType).Tolist();

lazy loading

모델에서 고객은 정의해야합니다

Public virtual string membershipType {get; set;}

따라서 지연로드를 쿼리 할 때 모든 참조 객체를로드하는 것이 훨씬 느리지 만 열망로드 쿼리는 관련 객체 만 선택합니다.


Glimpse와 같은 성능 진단 도구를 사용하고 여러 연결 및 쿼리가 하나만있는 지연로드 동안 둘 다 작동하는 방식을 확인합니다. 나는 그것들을 실질적으로 확인했습니다. 왜 그렇게 잘못 말했는지 언급하십시오.
Nuwan Dhanushka

#FakeCaleb 그의 코멘트를 제거했습니다
Nuwan Dhanushka에게

모드는 당신이 당신의 응답에서 어쨌든 내 댓글을 오해 나는이 대화를 계속하고있는 점을 보지 못했다, 내 댓글을 제거
FakeCaleb

당신은 정확한 요점을 언급하지 않았고 내 의견이 완전히 오해의 소지가 있다고 말했습니다. 잘못된 점을 언급하면 ​​나도 배울 수 있습니다.
Nuwan Dhanushka

나는 말로 인해 eager loading이 성능으로 인해 lazy loading보다 낫다는 것을 암시한다고 생각합니다. 이것이 사실이 아닌 시나리오를 생각할 수 있습니다.
FakeCaleb

-2
// Using LINQ and just referencing p.Employer will lazy load
// I am not at a computer but I know I have lazy loaded in one
// query with a single query call like below.
List<Person> persons = new List<Person>();
using(MyDbContext dbContext = new MyDbContext())
{
    persons = (
        from p in dbcontext.Persons
        select new Person{
            Name = p.Name,
            Email = p.Email,
            Employer = p.Employer
        }).ToList();
}

1
이 코드 스 니펫은 질문을 해결할 수 있지만 설명을 포함하면 게시물의 품질을 향상시키는 데 큰 도움이됩니다. 미래에 독자를 위해 질문에 답하고 있으며 해당 사용자는 코드 제안 이유를 모를 수 있습니다.
그는 이페이何一非

1
이 답변은 OP 질문을 전혀 다루지 않습니다. 영업 이익은 수행하는 방법에 대한 요구하지 않습니다 Lazy loading, 그는 "를 사용하는 경우에 대한 요구되는 Lazy loadingEager Loading"
미샤
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.