728x90
상품 리스트를 보여주는 ProductsView를 만들었다.
class ProductsView(View):
@input_validator
def get(self, request):
option = request.GET.get('option', None)
offset = int(request.GET.get('offset', 0))
limit = int(request.GET.get('limit', 0))
order = request.GET.get('order', 'id')
q = Q()
if option == 'new':
q = Q(is_new=True)
if option == 'sale':
q = Q(~Q(discount_percent=0))
products = Product.objects.filter(q).order_by(order)[offset:offset+limit]
results = [{
'id' : product.id,
'name' : product.name,
'price' : int(product.price),
'images':[image.url for image in product.image_set.all()]
}for product in products]
return JsonResponse({'results': results}, status=200)
간단하게 로직을 설명해보자면
쿼리 파라미터로 옵션을 신상여부와 세일여부를 받을 수 있고 해당하는 조건에 맞는 상품리스트를 Json파일로 넘겨주게 된다.
상품테이블은 이미지 테이블을 따로 두어서 이미지 테이블이 상품을 '참조' 하게 만들었다.
그래서 상품에 해당하는 이미지들을 조회하려면 역참조를 해야한다.
위와 같이 했을 때 데이터베이스에 몇번 쿼리가 날라가는지 살펴보자.

다른 옵션은 주지 않고 상품중에서 10개의 상품만 조회하는 요청을 보냈다.

충격적인 결과다. ㄴㅇㄱ
상품 10개의 데이터를 조회하는데 이미지 테이블에 각각 한번씩 쿼리를 날려서 총 11번의 쿼리가 날라가게된다.
정말 비효율적이다.
이제 prefetch_related를 사용해서 성능향상을 시켜보자
products = Product.objects.filter(q).prefetch_related('image_set').order_by(order)[offset:offset+limit]
이제 다시 쿼리를 확인해보자

2번으로 쿼리가 줄었다!!
SQL쿼리문을 살펴보면 image테이블에 10개를 한번에 조회하는 것을 알 수 있다.
그렇다 prefetch_related를 사용하면 데이터를 한번에 조회하고 캐싱해두었다가 필요할 때 쓰는 것이다.
또 데이터를 역참조할 때 사용한다.
'DotFriends' 카테고리의 다른 글
⚫️Dotfriends 페이징 기능 쿼리 성능 향상 시키기 (0) | 2021.10.16 |
---|---|
🚀 상품 리스트 조회 API분기 줄이기 (0) | 2021.09.25 |
📌 쿼리 파라미터 입력값에 따른 500에러 막기 (0) | 2021.09.24 |
⚫️ DotFriends 프로젝트 후기 (0) | 2021.09.12 |
제품 상세페이지 구현과 고민 01 (0) | 2021.09.05 |