django) 효율적으로 Create 하기 (feat. bulk_create)

렁호·2022년 5월 3일
0
post-thumbnail

Create

django에서 ORM을 사용해 데이터를 생성하는 방법은 기본적으로 두 가지가 있다.

  1. Create ORM
from models import Nothing

Nothing.objects.create(contents='test')
  1. Object method
from models import Nothing

n = Nothing(contents='test')
n.save()

위 두 가지의 방식 모두 내부적으로는 동일하게 동작하기 때문에 각자의 로직에 맞춰서 선택하면 된다.

데이터가 많다면 !?

문제는 위와 같은 단일 데이터가 아닌 다량의 데이터를 생성하거나 데이터를 밀어넣어야 할 때이다.

사실 일반적인 로직에서는 View에서 유저의 단일 request로 서버가 감당하기 힘들만큼의 데이터가 생성 될 일은 자주 있는 일은 아니다.

하지만 internal 환경에서는 충분히 자주 있는 일이다.

특히 백오피스로 자주 쓰이는 django의 특징을 생각한다면 왕왕 중요한 문제라고 할 수 있다.

그리고 이런 문제를 해결 하기 위해 django에서는 아주 기똥찬 ORM 'bulk_create'를 제공한다.

bulk_create() VS create()

과연 얼마나 큰 차이가 나는지 코드를 돌려가며 비교해보았다.

Create()

import datetime
from models import Nothing

start = datetime.now()

for i in range(5000):
    Nothing.objects.create(contents=f'test{i}')
time = datetime.now()-start

print(f'create() : {time}')
>> create() : 0:00:22.918623

bulk_create()

import datetime
from models import Nothing

start = datetime.now()

n_list = [Nothing(contents=f'test{i}') for i in range(5000)]

Nothing.objects.bulk_create(n_list)

time = datetime.now()-start

print(f'bulk_create : {time}')
>> bulk_create : 0:00:00.071007

엄청난 차이가 난다.

이렇게 시간 차이가 나는 이유는 두 가지다.

  • DB connection 횟수

일반적인 방식의 경우 DB 연결 -> 저장 -> DB 연결 해제의 과정을 반복 횟수만큼 해야 한다.

당연히 오래 걸릴 수 밖에 없다.

  • SQL

위의 이유로 DB에 날리는 SQL 또한 많이 달라지게 된다.
bulk_create의 경우 한번의 DB 연결로 Union All 을 사용하여 한 번에 데이터를 Insert 하는 반면 일반적인 ORM의 경우 Insert를 반복 횟수만큼 날리게 된다.

만약 SQL 한 번에 포함되는 생성 데이터 개수를 조절 하고 싶다면 Model.objects.bulk_create(object_list, batch_size=50) 이런식으로 batch_size 속성을 사용하여 변경 가능하다.

profile
식욕, 수면욕, 성욕 만땅

0개의 댓글