코딩일지/Django

[Django] Selected_related와 Prefetch_related

신유니버스 2021. 9. 11. 17:12

Selected_related와 Prefetch_related

이번에는 Selected_related와 Prefetch_related에 대해서 알아보고자 한다.

1차 프로젝트를 진행하면서 검색 기능에 필요한 로직을 구성하면서 정 참조와 역참 조하는 파일들을 불러오기 위해서 DataBase를 여러 번 Hit 하는 것 보게 되었고 Hit를 줄일수록 더 빠르게 처리될 수 있다는 것을 배워 Selected_related와 Prefetch_related를 활용하게 되었다.

 

※ Selected_related

  •  Selected_related는 foreign-key(one-to-one,many-to-one)를 사용하여 정 참조할 때 사용하여 QuerySet를 가져올 때, 미리 related objects까지 불러오는 함수입니다.
  •  비록 쿼리는 복잡해질지라도 database에서 가져온 data는 캐시에 남게되어 매번 부를 때마다 DB에 접근하지 않아도 된다.

 

products.models.py
mysql> products table
mysql> image table
mysql> category table

※ Selected_related 미사용

 

  •  Selected_related 함수를 사용하지 않을 시 위의 명령어처럼 매번 Product 클래스에서 category 클래스를 참조할 때마다 쿼리를 두 번씩 수행한다는 것을 알 수 있습니다.

 

※ Selected_related 사용

 

  • 위의 명령어가 복잡해지기는 하지만 select_related를 사용함으로써 DB에 한번 접근함으로써 원하는 값을 받아오는것을 알 수 있다.
  • foreign_key로 연결되어있는 데이터를 filter로는 전부 불러올 수 없기에 select_related를 쓰는 것이 처리속도를 더 빠르게 만들 수 있다.

 

Prefetch_related

  • Selected_related와 비슷한 용도로 사용되지만, 차이점은 모든 관계에서 사용 가능하다.
  • 역참조에서도 사용할 수 있다.

MtoM models.py
mysql> actors table
mysql> movie table
mysql> movie_actor table (관계테이블)

※ Prefetch_related 미사용

 

  •  Prefetch_related 함수를 사용하지 않을 시 위의 명령어처럼 매번 Movie 클래스에서 Actor 클래스를  MtoM로 참조할 때마다 쿼리를 두 번씩 수행한다는 것을 알 수 있습니다.

 

※ Prefetch_related 사용

 

  • Select를 사용할 때처럼 복잡해지지만 MtoM 관계를 대상으로 참조할 때 Data를 캐시에 담아두기에 불러오는데 수월하다

 

※ Prefetch_related 역참조에 사용 (selected_related의 products.models.py 사용)

 

  • Product는 자신을 정 참조하고 있는 image를 역참조 하기 위해서 lookup에 (_set)을 쓴다.
  • Prefetch_related를 사용하지 않으면 역참 조시에도 DB를 여러번 타격하게 되는데  Prefetch_related를 사용하게 되면 역참조시에 필요한 Data를 캐싱해두었다가 사용하는 것을 알 수 있다.

 

Prefetch_related 사용한 역참조

★ 데이터 베이스에 쿼리 조회수를 줄일 수 있다는 것을 확인하려면 아래의 링크에 들어가서 확인하시면 편합니다.

링크 = https://kingofsiliconvalley.tistory.com/18