TIL #40 select_related & prefetch_related
데이터베이스의 데이터를 가져오기 위해 query을 수행하는데, 초소한의 query로 최대한의 퍼포먼스(데이터베이스의 접근을 줄이고 처리 속도를 증가)를 내기 위해 select_related 와 prefetch_related을 사용한다.
이 둘은 최초 query를 통해 관련 데이터를 캐쉬에 저장하고, 필요한 데이터를 데이터베이스에서 가져다 쓴다는 공통점이 있지만, query 수행에 방식이나 용도에는 조금의 차이가 있다.
1. select_related
- 정참조 관계에서 사용
- JOIN을 사용하여 query 수행
- select_related 사용 전
- 코드
-query=> SELECT query가 계속해서 수행되고 있다.
- select_related 사용 후
- 코드=> 정참조 관계인 'series'와 'color__filtering_color'의 데이터들 같이 가져온다.
- query=> 한 번의 SELECT query 후 더 이상 query을 진행 하지 않는다.
2. prefetch_related
- 역참조, many to many, many to one 관계에서 쓰인다.
- select_related와는 다르르게 JOIN이 아닌 역참조 관계에서 별도의 2개의 query 수행 후 파이썬에서 join 한다.
- prefetch_related 예제
=> Category와 역참조 관계인 drink을 prefetch_related로 불러 오게 되면 category와 drink 각 각의 query가 수행 되는 것을 볼 수 있다.
=> prefetch_related로 query 수행 후 캐쉬에 저장 된 데이터를 사용해 별로의 query 수행 없이 data을 가져오는 것 을 볼 수 있다.
3. 주의 사항
Note
Remember that, as always with QuerySets, any subsequent chained methods which imply a different database query will ignore previously cached results, and retrieve data using a fresh database query. So, if you write the following:
>pizzas = Pizza.objects.prefetch_related('toppings')
>[list(pizza.toppings.filter(spicy=True)) for pizza in pizzas]
…then the fact that pizza.toppings.all() has been prefetched will not help you. The prefetch_related('toppings') implied pizza.toppings.all(), but pizza.toppings.filter() is a new and different query. The prefetched cache can’t help here; in fact it hurts performance, since you have done a database query that you haven’t used. So use this feature with caution!
요약: prefetch_related로 topping을 불러 왔어도 .filter는 다른 query을 수행하기 때문에 오히려 prefetch을 사용하는 것이 더 비효율적일 수 있다.
Author And Source
이 문제에 관하여(TIL #40 select_related & prefetch_related), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kgh239/TIL-40-selectrelated-prefetchrelated저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)