내가 만든 Django ORM(Queryset API)의 성능 테스트
실제 어느부분에서 쿼링이 이뤄지는지 코드를 실행하는 레벨에서 확인하거나, Shell 상에서도 해볼 수 있음
보통의 장고 프로젝트(페이지가 존재하는 경우)에는 django-debugger-toolbar
라는 것을 사용
하지만 우리는 API를 만들뿐, 이를 위해 페이지를 구성해서 디버거를 실행시키는 것은 자원 낭비
서버 실행시 코드 실행때마다 쿼리가 찍히게 설정.
예시)
#settings.py
LOGGING = {
'disable_existing_loggers': False,
'version': 1,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'level': 'DEBUG',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
},
}
아래와 같이 옵션을 추가하면 디버깅을 통해 볼 수 있음
예시)
#settings.py
LOGGING = {
'disable_existing_loggers': False,
'version': 1,
'formatters': {
'verbose': {
'format': '{asctime} {levelname} {message}',
'style': '{'
},
},
'handlers': {
'console': {
'class' : 'logging.StreamHandler',
'formatter' : 'verbose',
'level' : 'DEBUG',
},
'file': {
'level' : 'DEBUG',
'class' : 'logging.FileHandler',
'formatter' : 'verbose',
'filename' : 'debug.log',
},
},
'loggers': {
'django.db.backends': {
'handlers' : ['console','file'],
'level' : 'DEBUG',
'propagate': False,
},
},
}
쿼리셋.filter()
등을 쓴다고 해서 그 때 데이터베이스를 호출하지 않음
(대신 queryset.query
안에 호출 조건들의 속성값들을 저장)
그 뒤 쿼리셋.filter()[0]
, 반복문, list
등을 쓸 때 데이터베이스에 호출(쿼리셋을 평가)을 보냄
리스트 등을 사용하면 쿼리셋을 미리 호출해서 결과값에 저장두고 그 다음에 그 결과값에서 쿼리셋을 꺼내 쓸 수 있음
(두 번 호출하지 않고 한 번만 호출 가능)
반복문을 사용할 때 테이블 바깥에 있는 다른 테이블의 값을 바로 정참조하여 가져오면 연산이 너무 많이 발생
--> Eager Loading
을 사용하여 해결
반복문을 사용할 때 테이블 바깥에 있는 다른 테이블의 값을 바로 역참조하여 가져오면 연산이 너무 많이 발생
--> Eager Loading
을 사용하여 해결
prefetch_related
를 사용했는데도 연산이 많은 경우
--> Prefetch
를 사용하여 해결
테이블.objects.all().select_related('다른테이블명')
을 사용하여 해결 가능
테이블.objects.all().prefetch_related('다른테이블명')
을 사용하여 해결 가능
select_related
는 테이블을 join
해서 한 번에 가져오고, prefetch_related
는 루트 쿼리(테이블.objects.all()
)를 날리고 추가 쿼리를 날림테이블.objects.all().prefetch_related(Prefetch('다른테이블명', to_attr='가져올속성명1'),Prefetch('다른테이블명', to_attr='가져올속성명2'))
을 사용하여 해결 가능
예시)
loadtest -n 횟수 url