less than 1 minute read

1. 프롤로그

Django ORM을 활용하면 편리하게 RDBMS의 Relation을 파이썬의 object로 mapping하여 제어 할수 있다.

Django ORM은 하나의 post에서 다루기에는 양이 방대하여 여러개의 포스트로 나누어서 ORM을 적용한 사례나 ORM의 특징(cache, lazy특성 등등)에 대해 다루어보려 한다.

2. Lazy Loading

if professorName is not False:
    queryset = queryset.filter(professor=professorName)
if semester is not False:
    queryset = queryset.filter(semester__in=semester)
if subject is not False:
    queryset = queryset.filter(subject__contains=subject)

if sort is False or sort == 'recently': 
    queryset = queryset.order_by('-year')
else: 
    queryset = queryset.order_by('-star') 
return queryset #여기서 쿼리가 호출이 된다.

Lazy-Loading 방식을 사용하면 ORM에서 명령을 실행할 때마다 데이터베이스에서 데이터를 가져오는 것이 아니라 모든 명령 처리가 끝나고 실제로 데이터를 불러와야 할 시점이 왔을 때 데이터베이스에 쿼리를 실행하는 방식을 의미한다.

3. N + 1 문제

class FlowerListSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField()
    purposes = PurposeSerializer(many=True, read_only=True)
    image = serializers.SerializerMethodField('get_thumbnail')
    star = serializers.FloatField()

이경우 쿼리는 몇번 실행될까? flower들을 읽어오는데 한번, flower들의 갯수가 n개라고 가정시 n+1 번의 쿼리가 실행된다. (nested serializer하나당 한번) 이는 DB에 부하를 발생시키는 문제점이 있으므로 Eager Loading 기법으로 해결해보자

4. Eager Loading

Eager Loading은 Lazy-Loading과 달리 사전에 사용할 데이터를 포함하여 쿼리를 날리기 때문에 비효율적인 쿼리 요청을 줄일수 있다. Django ORM에서 prefetch_related 기능을 이용하면 한번에 미리 읽어와서 쿼리실행 횟수를 줄일수 있다.

queryset = queryset.prefetch_related('purposes')

5. 참고한 자료

https://show-me-the-money.tistory.com/48

Leave a comment