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_attr
과 Prefetch
클래스를 이용하면 DB쿼리를 또 줄일 수도 있다.
- prefetch는 다대다관계와 역참조 관계일 때 많이 사용한다. 왜냐하면 불특정 다수의 Row를 참조해야되기 때문이긴한데, 나는 편하게 다대다관계와 역참조일때는 공식처럼 prefetch를 적용한다.
- 물론, DB 쿼리를 확인하고 보다 효율적인 방식이 따로 있는지 검사한다.
- select_related는 일대일(OnetoOne)관계이거나 일대다(OnetoMany)를 정참조일 때 사용해야 대부분의 경우에서 Query를 줄일 수 있다.
내용이 아직 정리되지 않아 추후 추가포스팅할 예정