TIL | Django - ORM 최적화

송치헌·2021년 9월 19일
0

TIL | Wecode - Django

목록 보기
17/18
post-thumbnail

📔Lazy loading과 eager loading

lazy loading : 지연 로딩
eager loading : 즉시 로딩

django에서는 DB에 언제 접근하는지 알아보자.

Lazy Loading


lazy loading은 말그대로 지연 로딩이다. 그냥 바로 호출할 때마다 DB에 가서 불러오면 되는데 왜 지연 로딩을 할까?

DB접근을 최소화 하여 무리가 가지 않도록 하기 위함이다.

바로 예시로 들어가보면

  • filter

    query가 0번 호출된 것을 볼 수 있다.
    이 말은 filter를 사용해도 DB에 직접 접근하는 것이 아니다.
    그렇다면 filter를 쓰면 데이터를 볼 수가 없는 것일까?
    정답은 땡!

    이렇게 쿼리셋을 불러올 수 있다.

다른 예시를 보자.

  • annotate

    annotate도 마찬가지로 쿼리를 호출하지 않는다.

    filter도 QuerySet, annotate도 QuerySet...슬슬 냄새가 난다.

이번엔 다른 경우를 보자.

  • get

    이번엔 쿼리문이 하나 늘어났다!
  • len(), list(), indexing

    세 경우 다 쿼리가 1개씩 평가되었다.
    이렇게 쿼리가 즉시 일어나는 경우가 eager loadin이다.

그렇다면 여기서 문제, 다음과 같은 경우에는 호출이 몇 번 일어나는가?


.
.
.
.
.
.
.
.
.
.
.
.
.
.

정답은 한 번이다.

위에서 list()indexing 둘 다 한번씩 쿼리가 평가된다면서 왜 둘 다 쓰니까 1번만 평가되는거지?

Caching


그 정답은 여기에 있다.


위의 7번 케이스에서 qs[0]list(qs)를 순서를 바꿔서 써보니 쿼리가 두 번 일어났다..

그 말은 list()를 먼저 쓴 후 indexing()을 쓰면 indexing()에서 쿼리가 일어나지 않는다는 뜻이다.

즉, list()에서 Caching이 일어났다는 것이다.

_result_cache를 보면 처음엔 캐싱이 일어나지 않다가 list()를 사용한 후 캐싱이 일어난 것을 볼 수 있다. 즉, list()를 사용했을 때 쿼리가 한 번 평가되고 그 쿼리가 캐싱되어서 나중에 호출했을 때는 저장된 캐시에서 꺼내어 사용한다는 것을 알 수 있다.

이 것을 통해 알 수 있는 것은

이렇게 쿼리셋에서 매번 인덱싱으로 값을 가져오면 매번 쿼리가 일어난다.

따라서 이렇게 list()로 캐싱을 해서 거기서 꺼내 쓰는 것이 더 DB접근을 최소화 할 수 있다.

profile
https://oraange.tistory.com/ 여기에도 많이 놀러와 주세요

0개의 댓글