본문 바로가기
wecode/TIL 정리

Django TIL - 2. Select Related, Prefetch Related

by 왕거 2020. 9. 17.

중요한 개념이고, 위코드 2차 프로젝트를 진행하면서 쿼리 시간 단축을 위한 여러 방법들을 사용하다보니 이 개념에 대한 이해가 너무 부족했다는 점을 알게 되었다.

 

Select Related와 Prefetch Related 두 방법 모두 관계를 통해서 여러개의 테이블에 있는 데이터들을 사용할 수 있도록 하는 방법들이다.

 

나중에 까먹더라도 이 포스트보면 다시 기억할 수 있도록 작성해봐야겠다.

 

Select Related?

  • SQL 문법 중 Join을 실시하는 Django의 ORM이다.
  • 일반적인 Many to One 또는 One to One 관계의 외래키 컬럼을 사용해서 참조관계에 있는 테이블을 지정한다.
  • 정참조 관계에 있는 테이블에 사용한다.
  • 사용하면 Join을 완료한 데이터를 DB로 부터 가져온다.
  • 하나의 쿼리로 진행된다.

Select Related ORM 사용 예제와 실제 실행되는 SQL RAW Query

  • 이 ORM의 장점은 여러번의 쿼리를 한번의 쿼리로 대체할 수 있다는 점이다.

Select Related를 사용한 방법
 Select Related를 사용하지 않은 방법

  • 2차 프로젝트를 진행하면서 쿼리의 수와 속도가 굉장히 밀접한 관계를 가지고 있다는 걸 알게되어서 이런 테이블의 관계들을 지정하는 모델링의 중요성을 다시 한번 깨달을 수 있었다.
  • 2차 프로젝트 진행 중에 속도를 개선하는데에 굉장히 큰 도움이 된 ORM으로서 개선 전에는 제품 하나 하나의 정보를 위해서 쿼리를 각각 진행했다면, 개선 후에는 전체 제품 데이터를 한번에 쿼리 한 후에 가져온 데이터를 사용하는 식으로 변경했다. 작동시간의 개선은 거의 10분에 1정도로 괜찮은 퍼포먼스를 보여줬다.
  • 테이블의 여러 Row와 관계가 설정된 다른 테이블의 Row들까지 연결해서 가져온 후에는 DB에 추가적인 쿼리 없이, 이미 가져온 데이터들을 사용할 수 있다.  -> 쿼리 결과의 캐싱
  • 상황에 따라 개별 쿼리가 좋은 방법일 수도, Select Related 쿼리가 좋은 방법일 수도 있다. 무작정 한가지의 경우만 고집하는 것은 오히려 비효율적인 구조를 만들어 낼 수 있다.

 

 

Prefetch Related?

  • Select Related와 비슷하게 Join을 수행하는 ORM
  • Many to Many 또는 Many to One 관계에서 역참조를 진행할 때 사용한다.
  • 사용하면 하나의 쿼리가 아닌 별도의 쿼리들이 수행되며 해당 쿼리의 결과를 파이썬에서 Join

Prefetch Related를 수행했을 때 실행되는 두개의 SQL RAW Query를 확인할 수 있다.

  • 기본적으로 역참조에 사용되는 이름은 '테이블명_set'를 사용한다. 아니면 해당 App의 Models.py에서 참조하는 컬럼에 Related_name옵션을 사용해서 역참조 시에 사용할 이름을 직접 지정해줄 수도 있다.
  • Prefetch Related의 경우에는 역참조 관계를 다루기 위한 ORM이다 보니 이해가 조금 어렵다.
  • 2차 프로젝트 동안의 속도 개선을 위한 쿼리 정비 작업 중에도 Prefetch Related를 적용해보지 못했다. 역참조하는 테이블의 데이터에 접근하면 꼭 한번씩은 DB에 추가적인 접근을 하는 게 확인되어서인데 반복문을 많이 사용하다보니 제품별로 하나의 쿼리가 생기는 건 제품 전체로 보면 수많은 쿼리가 추가되는 꼴이라서 더더욱 사용을 할 수 없었다.
  • 정참조 관계에 사용하는 Select Related와 달리 개념적으로 조금 복잡해서 이해하기 더 어려운 것 같다.

 

'wecode > TIL 정리' 카테고리의 다른 글

자료구조 TIL - 4. Tree  (0) 2020.09.03
Django TIL - 1. Unit Test  (0) 2020.08.22
자료구조 TIL - 3. Stack, Queue  (0) 2020.08.22
자료구조 TIL - 2. Set, Dictionary, Hash  (0) 2020.08.12
위코드 Foundation - Bcrypt, JWT 테스트  (0) 2020.08.12