[TIL] select_related와 prefetch_related

야란·2021년 6월 27일
0
post-thumbnail

select_related와 prefetch_related

Django를 잘 사용하기 위해선 쿼리수를 줄이고 효율적으로 사용해야 한다 그 중에 쿼리수를 줄여주는 2가지의 method

(ORM : Model class를 통해서 객체를 만들고 이 객체를 통해 DB에 접근하는 방법)
(QuerySet : objects를 사용하여 다수의 데이터를 가져오는 함수 사용시 반환되는 객체)

  • select_related :
    SQL Query문의 JOIN을 사용해서 Foreign-Key를 사용해서 정참조 할때 사용하고, 미리 related objects까지 가져온다(Eager Loading). cache에 가져온 data를 남겨서 매 Query마다 DB에 접근하지 않는 이점이 있다.
    접근 빈도수를 확 줄여준다!
    (one-to-one , one-to-many)
    (1:N에서 N이 사용)
  • prefetch_related:
    select_related와 마찬가지로 DB에 접근하는 횟수를 줄여주는 이점이 있다
    하지만 prefetch_related의 경우에는 추가 Query를 통해 데이터를 가져온다
    (many-to-one, many-to-many, 역참조)
    (1:N에서 1이 사용)

더 나아가 Prefetch()를 써야 하는 경우가 있음
prefetch_related의 필드에 추가적인 조건(filter등)을 걸고싶을때가 있는데
그때는 Prefetch()객체를 사용한다.
이건 좀 더 공부해야 이해가 갈거 같은데...

Django SQL query Logging을 통해서 쿼리가 어떤식으로 발생하는지 shell에서 확인가능하게 해줌

LOGGING = {
    'disable_existing_loggers': False,
    'version': 1,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False,
        },
    },
}

그리고 사실 우리가 하는 a = Room.objects.all()는
우선 아무 동작도 하지 않고 있다가 a.name같은 호출이 있을때 작동한다!
= lazy loading

https://docs.djangoproject.com/en/3.2/ref/models/querysets/

profile
🤦🏻‍♀️ 아차차

0개의 댓글