EF Core Lazy Loading과 Eager Loading 완벽 정리
1. EF Core에서 로딩 전략이 중요한 이유
안녕하세요! 오늘은 EF Core에서 자주 혼동되는 개념 중 하나인 Lazy Loading과 Eager Loading을 친근한 예제와 함께 살펴보겠습니다. 데이터베이스를 다루다 보면 단순히 데이터를 가져오는 것만으로도 성능이 크게 달라질 수 있어요. 잘못된 로딩 전략은 불필요한 쿼리 발생으로 성능 저하를 초래할 수 있으니, 상황에 맞는 전략 선택이 중요합니다.
2. Lazy Loading이란?
Lazy Loading은 관련 데이터를 실제로 사용할 때까지 조회를 지연하는 방식입니다. 즉, 처음에는 기본 엔티티만 로드하고, 관련된 데이터가 필요할 때 EF Core가 추가 쿼리를 자동으로 실행합니다.
예를 들어, 도서(Book)와 저자(Author) 관계가 있다고 가정해봅시다. Lazy Loading을 사용하면 책 데이터를 가져올 때는 저자 정보가 조회되지 않다가, 코드에서 저자 데이터를 접근할 때 쿼리가 실행됩니다.
using Microsoft.EntityFrameworkCore;
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
// Lazy Loading
public virtual Author Author { get; set; }
}
public class Author
{
public int Id { get; set; }
public string Name { get; set; }
}
Lazy Loading을 사용하려면 virtual
키워드와 Microsoft.EntityFrameworkCore.Proxies
패키지가 필요합니다. Program.cs에서 다음과 같이 설정할 수 있어요.
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(connectionString)
.UseLazyLoadingProxies());
장점: 필요한 데이터만 조회하므로 초기 로딩 속도가 빠릅니다.
단점: 반복적으로 관련 데이터를 접근하면 N+1 쿼리 문제가 발생할 수 있어 주의해야 합니다.
3. Eager Loading이란?
Eager Loading은 관련 데이터를 처음부터 한 번의 쿼리로 가져오는 방식입니다. 따라서 N+1 문제를 방지하고, 한 번에 필요한 데이터를 모두 조회할 때 유리합니다.
var books = await _context.Books
.Include(b => b.Author)
.ToListAsync();
위 예제에서 Include
메서드를 사용하면, 책 데이터를 가져올 때 저자 정보도 함께 조회됩니다. 장점: 쿼리 수를 최소화하고 성능 최적화 가능.
단점: 필요 없는 데이터를 미리 조회하면 메모리 사용량이 늘어날 수 있습니다.
4. 언제 Lazy Loading, 언제 Eager Loading을 사용할까?
- Lazy Loading 추천 상황: 관련 데이터를 자주 사용하지 않거나, 초기 로딩 속도가 중요한 경우.
- Eager Loading 추천 상황: 관련 데이터를 반드시 함께 사용하며, 쿼리 수를 줄이는 것이 중요한 경우.
- 혼합 사용 가능: 일부 엔티티는 Lazy, 일부는 Eager로 전략을 혼합하여 성능 최적화.
실무에서는 상황과 데이터 구조에 맞춰 전략을 선택하는 것이 중요하며, 성능 모니터링을 통해 쿼리 실행 횟수를 확인하는 습관이 필요합니다.
5. 예제 프로젝트에서 실습해보기
작은 예제 프로젝트를 만들어 Lazy Loading과 Eager Loading을 비교해볼게요.
var book = await _context.Books.FirstOrDefaultAsync(b => b.Id == 1);
// Lazy Loading: 접근 시 쿼리 발생
var authorName = book.Author.Name;
// Eager Loading: Include로 미리 조회
var bookWithAuthor = await _context.Books
.Include(b => b.Author)
.FirstOrDefaultAsync(b => b.Id == 1);
var eagerAuthorName = bookWithAuthor.Author.Name;
실제 프로젝트에서 로그를 확인하면 Lazy Loading 시 쿼리가 추가로 실행되는 것을 확인할 수 있어요. 반대로 Eager Loading은 처음부터 한 번의 쿼리로 관련 데이터를 모두 가져옵니다.
6. 성능 최적화 팁
- Lazy Loading은 N+1 문제 발생 가능성을 항상 인지하고, 필요 시 Eager Loading으로 전환.
- Include와 ThenInclude를 활용하면 복잡한 관계도 한 번에 조회 가능.
- 쿼리 실행 로그를 확인하여 불필요한 쿼리가 발생하지 않도록 모니터링.
- 대용량 데이터 조회 시
AsNoTracking()
을 사용하여 성능 개선. - 프로젝트 초기 설계 단계에서 데이터 접근 패턴을 고려해 로딩 전략을 결정하면 유지보수가 쉬워집니다.
7. 마무리
오늘은 EF Core에서 Lazy Loading과 Eager Loading의 차이와 활용법을 예제와 함께 자세히 살펴보았습니다. 처음에는 개념이 헷갈릴 수 있지만, 직접 프로젝트에 적용하면서 데이터 조회 패턴을 관찰하면 어느 전략을 써야 하는지 감이 잡히실 거예요. EF Core를 잘 활용하면 데이터베이스와 객체 간의 매핑을 자연스럽게 관리할 수 있고, 성능 최적화까지 챙길 수 있습니다.