DB에 날리는 Query를 줄여보자 - 2편 prefetch_related

0

DJANGO

목록 보기
9/9
post-thumbnail

Prefetch vs Select

먼저 select_related 와 prefetch_related의 차이점을 Join을 DB가 하느냐 아니면 Python이 하느냐다. 앞써 select_related는 DB query에 Join 구절이 들어간 것을 확인할 수 있다. 하지만, prefetch를 하게되면 where in 문이 SQL에서 발생되는 것을 확인 할 수 있는데, 이것이 나는 가장 큰 차이점을 이해할 수 있는 열쇠라고 생각한다.

  • Select_related를 하게되면 A테이블의 B 외부키에 해당하는 테이블을 Join해서 해당 B 테이블의 Column을 합쳐서 반환
  • 하지만, A테이블이 B 테이블과 다대다(ManytoMany)관계에 있을경우, 각각의 A 객체의 B 테이블을 Join하기 때문에 여러개의 A 객체에 대한 각각의 DB 쿼리가 발생되기 때문에 비효율적이다.
  • 그렇기 때문에 다대다관계일 경우 select_related 보다 prefetch_related를 사용한다.
  • Prefetch는 임시저장이라고 생각하면 편하다. DB의 쿼리문을 처음에 날릴 때 임시저장할 다른 테이블의 데이터를 선정해서 임시저장한다.
  • 그 다음 그 prefetch한 테이블의 데이터가 필요할 때 저장된 테이블의 데이터로 Query를 보내서 불러오고, Python으로 해당 데이터를 돌린다.

  • 위에서 DB 쿼리를 추가로 보내서 데이터를 python에서 보낸다고 했는데, 사실 이 부분도 어느정도 개선이 가능하다. to_attrPrefetch 클래스를 이용하면 DB쿼리를 또 줄일 수도 있다.
  • prefetch는 다대다관계와 역참조 관계일 때 많이 사용한다. 왜냐하면 불특정 다수의 Row를 참조해야되기 때문이긴한데, 나는 편하게 다대다관계와 역참조일때는 공식처럼 prefetch를 적용한다.
  • 물론, DB 쿼리를 확인하고 보다 효율적인 방식이 따로 있는지 검사한다.
  • select_related는 일대일(OnetoOne)관계이거나 일대다(OnetoMany)를 정참조일 때 사용해야 대부분의 경우에서 Query를 줄일 수 있다.

내용이 아직 정리되지 않아 추후 추가포스팅할 예정

profile
# 개발 # 컴퓨터공학

0개의 댓글