django에서 ORM을 사용해 데이터를 생성하는 방법은 기본적으로 두 가지가 있다.
from models import Nothing
Nothing.objects.create(contents='test')
from models import Nothing
n = Nothing(contents='test')
n.save()
위 두 가지의 방식 모두 내부적으로는 동일하게 동작하기 때문에 각자의 로직에 맞춰서 선택하면 된다.
문제는 위와 같은 단일 데이터가 아닌 다량의 데이터를 생성하거나 데이터를 밀어넣어야 할 때이다.
사실 일반적인 로직에서는 View에서 유저의 단일 request로 서버가 감당하기 힘들만큼의 데이터가 생성 될 일은 자주 있는 일은 아니다.
하지만 internal 환경에서는 충분히 자주 있는 일이다.
특히 백오피스로 자주 쓰이는 django의 특징을 생각한다면 왕왕 중요한 문제라고 할 수 있다.
그리고 이런 문제를 해결 하기 위해 django에서는 아주 기똥찬 ORM 'bulk_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
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 연결 -> 저장 -> DB 연결 해제의 과정을 반복 횟수만큼 해야 한다.
당연히 오래 걸릴 수 밖에 없다.
위의 이유로 DB에 날리는 SQL 또한 많이 달라지게 된다.
bulk_create의 경우 한번의 DB 연결로 Union All 을 사용하여 한 번에 데이터를 Insert 하는 반면 일반적인 ORM의 경우 Insert를 반복 횟수만큼 날리게 된다.
만약 SQL 한 번에 포함되는 생성 데이터 개수를 조절 하고 싶다면 Model.objects.bulk_create(object_list, batch_size=50)
이런식으로 batch_size 속성을 사용하여 변경 가능하다.