프로젝트 진행 중 상세 페이지의 데이터와 댓글 데이터의 로딩 시간이 느려도 너~무 느려서 (내가 사용자였으면 나갔을만한 로딩 시간..) ORM 최적화를 진행하기로 했다.
LOGGING = {
'disable_existing_loggers': False,
'version' : 1,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'level': 'DEBUG',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False
}
},
}
import functools, time
from django.db import connection, reset_queries
from django.conf import settings
def query_debugger(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
reset_queries()
number_of_start_queries = len(connection.queries)
start = time.perf_counter()
result = func(*args, **kwargs)
end = time.perf_counter()
number_of_end_queries = len(connection.queries)
print(f"------------------------------------------------------")
print(f"Function : {func.__name__}")
print(f"Number of Queries : {number_of_end_queries-number_of_start_queries}")
print(f"Finished in : {(end - start):.2f}s")
print(f"------------------------------------------------------")
return result
return wrapper
------------------------------------------------------
Function : get
Number of Queries : 103
Finished in : 23.45s
------------------------------------------------------
@query_debugger
def get(self, request, project_id):
comments = Comment.objects.filter(project_id=project_id)
comments._result_cache
comment_list = [{
'user_id' : comment.user_id,
'nickname' : comment.user.nickname,
'description' : comment.description,
} for comment in comments
]
return JsonResponse({'comments':comment_list}, status=200)
N+1 problems
comment에서 user Instance에 접근하는 과정에서 많은 쿼리가 발생하였다.
(0.186) SELECT `projects`.`id`, `projects`.`created_at`, `projects`.`updated_at`, `projects`.`name`, `projects`.`user_id`, `projects`.`aim_amount`, `projects`.`description`, `projects`.`end_date`, `projects`.`category_id`, `projects`.`main_image_url`, `projects`.`isvisible`, `projects`.`isdeleted` FROM `projects` WHERE `projects`.`id` = 4 LIMIT 21; args=(4,)
(0.189) SELECT `users`.`id`, `users`.`email`, `users`.`nickname`, `users`.`password`, `users`.`kakao`, `users`.`google`, `users`.`auth_level`, `users`.`isdeleted` FROM `users` WHERE `users`.`id` = 3 LIMIT 21; args=(3,)
@query_debugger
def get(self, request, project_id):
comments = Comment.objects.filter(project_id=project_id).select_related('user')
comments._result_cache
comment_list = [{
'user_id' : comment.user_id,
'nickname' : comment.user.nickname,
'description' : comment.description,
} for comment in comments
]
return JsonResponse({'comments':comment_list}, status=200)
(0.208) SELECT `comments`.`id`, `comments`.`user_id`, `comments`.`project_id`, `comments`.`description`, `users`.`id`, `users`.`email`, `users`.`nickname`, `users`.`password`, `users`.`kakao`, `users`.`google`, `users`.`auth_level`, `users`.`isdeleted` FROM `comments` INNER JOIN `users` ON (`comments`.`user_id` = `users`.`id`) WHERE `comments`.`project_id` = 4; args=(4,)
------------------------------------------------------
Function : get
Number of Queries : 3
Finished in : 2.39s
------------------------------------------------------