[Django] select_related()

hukim·2020년 11월 11일
0

Django

목록 보기
10/12
post-custom-banner

select_related는 하나의 QuerySet을 가져올 때, 한꺼번에 related objects들까지 불러오게 하는 메소드입니다.

query문이 다소 복잡해질수도 있으나, 불러온 데이터들은 모두 cache에 남아있게 되기 때문에 DB에 다시 접근해서 select 하지 않아도 됩니다. DB에 접근하는 수가 줄어들면 당연히 성능적인 면에서도 효과적입니다.

select_related는 SQL의 JOIN을 사용하는 특성상 정참조 foreign-key이거나 one-to-one과 같은 single object에서만 사용이 가능하다는 한계가 있습니다.

class Career(models.Model):
	name = models.CharField(max_length = 50)

class Salary(models.Model):
	salary = models.IntegerField(default = 0)
        career = models.ForeignKey(Career, on_delete = models.CASCADE)

위와 같은 간단한 모델이 있다고 가정해보겠습니다.

salary테이블에서 career테이블을 정참조 하고있는 관계입니다.

Salary.objects.get(id=1).career.name

salary의 id가 1인 객체의 career name을 가져왔습니다.

SQL Logger에 보면 SELECT가 각 테이블 마다 한 번씩 사용된 것을 확인할 수 있습니다.
salary테이블에서 한번 SELECT하고 그 다음 career테이블에서 SELECT 했습니다.

총 두번의 SELECT문을 사용한 셈인데 지금은 하나의 객체에 대해서 진행했기 때문에 SELECT문을 한번 더 사용한다고해서 크게 무리가 가지는 않습니다만, for문을 돌려서 여러 객체에 대해서 데이터를 조회해야 할 경우에는 그만큼 SELECT문을 많이 사용하게 되기 때문에 데이터의 양이 많아지면 많아질수록 성능적인 면에서 비효율적이게 됩니다.

Salary.objects.select_related('career').get(id=1).career.name

이번에는 select_related를 이용해서 똑같이 id가 1인 객체의 career name을 가져왔습니다.

결과는 똑같이 나오지만 SQL Logger에서는 SELECT를 단 한번만 사용했습니다.
그 차이점은 SQL 문에서 JOIN을 이용해서 참조된 테이블에 대한 내용을 가져왔기 때문입니다.
처음 SELECT를 할 때 related objects(career)까지 한꺼번에 뽑아와서 cache에 저장해놓고 다음번에 가져오려고 하면 DB에 접근하지 않아도 cache에서 꺼내 쓰면 됩니다.

select_related를 활용하면 같은 결과를 얻을 수 있으면서 성능적인면에서 훨씬 효율적으로 작성할수 있습니다.

post-custom-banner

0개의 댓글