我已经创建了一个自定义manage.py
命令:
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
from photos.models import Person
class Command(BaseCommand):
help = 'Pre-populate database with initial data'
def _create_people(self, user):
for i in range(0, 100):
person = Person(first_name='FN', surname='SN', added_by=user)
person.save()
def handle(self, *args, **options):
user = User.objects.get(username="user1")
self._create_people(user)
我已经执行handle()
执行,如果我没有person.save()
则需要大约0.02秒,如果我保存,则每Person
大约需要0.1秒。数据库是sqlite,我相信它应该更快。什么可以解释这种糟糕的表现,我该如何改进呢?
答案 0 :(得分:5)
<强>分析:强>
def _create_people(self, user):
for i in range(0, 100):
person = Person(first_name='FN', surname='SN', added_by=user)
# Hits the database for each save.
person.save()
此函数将在数据库中100次并自动提交,这就是导致性能低下的原因(与MySQL或PostgreSQL相比,没有考虑sqlite的低性能)。
<强>改进:强>
在这种情况下,您需要的是bulk_create
,它将使用类构造函数创建的对象数组作为输入。所以可能的解决方案如下:
def _create_people(self, user):
person_data = {"first_name": "FN", "surname":"SN", "added_by": user}
person_list = [Person(**person_data) for i in range(100)]
Person.objects.bulk_create(person_list)
默认情况下,
bulk_create
无论有多少个对象都会命中数据库,除了在SQLite中(在SQLite中,每个查询大约999个)。 可以通过指定在单个查询中创建多少个对象 参数batch_size
。
<强> NB:强>
- 不会调用save(),也不会发送相关信号。
- 不适用于m2m关系。