Hamutaro - Hamtaro 4

Backend/Java

[JPA] JPA ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘ 2 - ์ฆ‰์‹œ ๋กœ๋”ฉ(EAGER) vs ์ง€์—ฐ ๋กœ๋”ฉ(LAZY)

carsumin 2025. 11. 12. 16:02
์ฆ‰์‹œ ๋กœ๋”ฉ (EAGER)
  • ์—ฐ๊ด€๋œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ ํ•จ๊ป˜ ๋ฐ”๋กœ ์กฐํšŒ
    • ์กฐํšŒ ์‹œ์ ์— ์กฐ์ธ์ด ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰
@ManyToOne(fetch = FetchType.EAGER)

 

 

์ง€์—ฐ ๋กœ๋”ฉ (LAZY)
  • ์—ฐ๊ด€๋œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•  ๋•Œ ์กฐํšŒ
    • ์ฒ˜์Œ์—๋Š” ํ”„๋ก์‹œ ๊ฐ์ฒด์—๋งŒ ๋„ฃ์–ด๋‘๊ณ  ํ•„๋“œ ์ ‘๊ทผ ์‹œ์ ์— DB ์กฐํšŒ
@ManyToOne(fetch = FetchType.LAZY)

 

 

์‹ค์ œ SQL ์ฐจ์ด
  • ์˜ˆ์‹œ
    • OAuthAccount -> Member (ManyToOne)
  • EAGER
    • ๋ฌด์กฐ๊ฑด Member๊นŒ์ง€ ๊ฐ™์ด ์กฐํšŒ
OAuthAccount account = repository.findById(1L);
SELECT oa.*, u.*
FROM oauth_accounts oa
LEFT JOIN users u ON oa.user_id = u.id
WHERE oa.id = 1;

 

  • LAZY
    • Member๋Š” ์•„์ง ์กฐํšŒ ์•ˆ ๋จ
OAuthAccount account = repository.findById(1L);
SELECT * FROM oauth_accounts WHERE id = 1;

 

  • Member๋ฅผ ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•  ๋•Œ
account.getMember().getEmail();
SELECT * FROM users WHERE id = ?;

 

 

ํ”„๋ก์‹œ(Proxy)
  • JPA๋Š” ์‹ค์ œ Member ๋Œ€์‹  ๊ฐ€์งœ ๊ฐ์ฒด๋ฅผ ๋จผ์ € ๋„ฃ์–ด๋‘ 
  • ์ด ๊ฐ€์งœ ๊ฐ์ฒด๋Š”
    • id ๊ฐ’์€ ์•Œ๊ณ  ์žˆ์Œ
    • ์‹ค์ œ ํ•„๋“œ ์ ‘๊ทผ ์‹œ DB ์กฐํšŒ

 

LAZY๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 
  • ๋ถˆํ•„์š”ํ•œ ์กฐ์ธ ๋ฐฉ์ง€
    • ๋ชจ๋“  ์—ฐ๊ด€ ์—”ํ‹ฐํ‹ฐ๋ฅผ ๋‹ค ๊ฐ€์ ธ์˜ค๋ฉด ์„ฑ๋Šฅ ๋‚ญ๋น„
  • N+1 ๋ฌธ์ œ ์˜ˆ๋ฐฉ
    • EAGER๊ฐ€ ๋งŽ์•„์ง€๋ฉด ์—ฐ์‡„์ ์œผ๋กœ ์กฐ์ธ์ด ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ์˜ˆ์ƒ ๋ชปํ•œ ์ถ”๊ฐ€ ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒ
  • ์„ค๊ณ„ ์œ ์—ฐ์„ฑ
    • ์‹ค์ œ๋กœ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์กฐํšŒํ•˜๋„๋ก JPQL์ด๋‚˜ fetch join์œผ๋กœ ์ œ์–ด ๊ฐ€๋Šฅ

 

N+1 ๋ฌธ์ œ๋ž€
  • ์˜ˆ๋ฅผ ๋“ค์–ด ํšŒ์› 10๋ช…์„ ์กฐํšŒํ•˜๊ณ  ๊ฐ ํšŒ์›์˜ ๊ฒŒ์‹œ๊ธ€์„ ์ ‘๊ทผํ•˜๋ฉด
    • 1+10 = 11 ๋ฒˆ ์ฟผ๋ฆฌ --> ์ด๊ฒŒ N+1 ๋ฌธ์ œ
SELECT * FROM member;
SELECT * FROM post WHERE member_id = 1;
SELECT * FROM post WHERE member_id = 2;
...