[ Aight ] 장고 API 응답 성능, 쿼리 개선: get_all_aiTools_combinedCats

horiz.d·2023년 5월 5일
0

PJ: Aight

목록 보기
1/17

Django-silky를 활용해 프로파일링한 응답시간의 변화는 아래와 같다.

한번에 모든 카테고리데이터를 받아와 DICT에 저장해 활용하는 방향으로 수정하여 쿼리 수를 줄였고, 응답시간을 절반수준으로 개선했다.

BEFORE

@api_view(['GET'])
@csrf_exempt
def get_all_aiTools_combinedCats(request):
    try:
        ai_tools = AiTool.objects.prefetch_related('categories').all()
        if not ai_tools:
            raise AiTool.DoesNotExist
        serializer = AiToolSerializer(ai_tools, many=True)
        serialized_data = serializer.data
        print(serialized_data)
        
        # Transform the serialized data
        transformed_data = []
        for ai_tool in serialized_data:
            category_ids = ai_tool['categories']
            categories_ko = []
            categories_en = []
            
            for category_id in category_ids:
                category = AiToolCategory.objects.get(id=category_id)
                categories_ko.append(category.name_set['ko'][0])
                categories_en.append(category.name_set['en'][0])
            
            transformed_data.append({
                'id': ai_tool['id'],
                'imgUrl': ai_tool['imgUrl'],
                'ko': {
                    'name': ai_tool['name_set']['ko'],
                    'category': categories_ko,
                },
                'en': {
                    'name': ai_tool['name_set']['en'],
                    'category': categories_en,
                },
                'summary': ai_tool['summary'],
                'redirectUrl': ai_tool['redirectUrl'],
            })
        
        return JsonResponse({'aiTools': transformed_data}, status=status.HTTP_200_OK)
    except AiTool.DoesNotExist:
        return HttpResponse(status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        

AFTER

@api_view(['GET'])
@csrf_exempt
def get_all_aiTools_combinedCats(request):
    try:
        ai_tools = AiTool.objects.prefetch_related('categories').all()
        if not ai_tools:
            raise AiTool.DoesNotExist
        serializer = AiToolSerializer(ai_tools, many=True)
        serialized_data = serializer.data
        
        #AiToolCategory를 한번에 가져와 ID를 기준으로 사전에 저장 : 성능개선용 (DB쿼리 수 감소)
        all_categories = AiToolCategory.objects.all()
        category_dict = {category.id: category for category in all_categories}

        # 프론트-메인코어 인터페이스 맞게 가공
        transformed_data = []
        for ai_tool in serialized_data:
            category_ids = ai_tool['categories']
            categories_ko = []
            categories_en = []
            
            for category_id in category_ids:
                category = category_dict[category_id]
                categories_ko.append(category.name_set['ko'][0])
                categories_en.append(category.name_set['en'][0])
            
            transformed_data.append({
                'id': ai_tool['id'],
                'imgUrl': ai_tool['imgUrl'],
                'ko': {
                    'name': ai_tool['name_set']['ko'],
                    'category': categories_ko,
                },
                'en': {
                    'name': ai_tool['name_set']['en'],
                    'category': categories_en,
                },
                'summary': ai_tool['summary'],
                'redirectUrl': ai_tool['redirectUrl'],
            })
        
        return JsonResponse({'aiTools': transformed_data}, status=status.HTTP_200_OK)
    except AiTool.DoesNotExist:
        return HttpResponse(status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
profile
가용한 시간은 한정적이고, 배울건 넘쳐난다.

0개의 댓글