lazy loading : 지연 로딩
eager loading : 즉시 로딩
django에서는 DB에 언제 접근하는지 알아보자.
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번만 평가되는거지?
그 정답은 여기에 있다.
위의 7번 케이스에서 qs[0]
와 list(qs)
를 순서를 바꿔서 써보니 쿼리가 두 번 일어났다..
그 말은 list()
를 먼저 쓴 후 indexing()
을 쓰면 indexing()
에서 쿼리가 일어나지 않는다는 뜻이다.
즉, list()
에서 Caching
이 일어났다는 것이다.
_result_cache
를 보면 처음엔 캐싱이 일어나지 않다가 list()
를 사용한 후 캐싱이 일어난 것을 볼 수 있다. 즉, list()
를 사용했을 때 쿼리가 한 번 평가되고 그 쿼리가 캐싱되어서 나중에 호출했을 때는 저장된 캐시에서 꺼내어 사용한다는 것을 알 수 있다.
이 것을 통해 알 수 있는 것은
이렇게 쿼리셋에서 매번 인덱싱으로 값을 가져오면 매번 쿼리가 일어난다.
따라서 이렇게 list()
로 캐싱을 해서 거기서 꺼내 쓰는 것이 더 DB접근을 최소화 할 수 있다.