缓慢保存到 Django 数据库
Slow saving to Django database
我创建了一个自定义 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,我相信它应该更快。什么可以解释如此糟糕的表现,我该如何改进?
分析:
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 次并每次自动提交,这就是导致性能低下的原因(不考虑 sqlite 与 MySQL 或 PostgreSQL 相比的低性能)。
改进:
在您的案例中,您需要的是 bulk_create
,它将使用 class 构造函数 创建的对象数组作为输入。所以一个可能的解决方案如下:
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)
By default bulk_create
hits the DB once no matter how many objects, except in SQLite (In SQLite it's about 999 per query.).
How many objects can be created in a single query can be specified through
the parameter batch_size
.
注意:
- save() will not be called, and the related signals will not be sent.
- does not work with m2m relationships.
我创建了一个自定义 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,我相信它应该更快。什么可以解释如此糟糕的表现,我该如何改进?
分析:
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 次并每次自动提交,这就是导致性能低下的原因(不考虑 sqlite 与 MySQL 或 PostgreSQL 相比的低性能)。
改进:
在您的案例中,您需要的是 bulk_create
,它将使用 class 构造函数 创建的对象数组作为输入。所以一个可能的解决方案如下:
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)
By default
bulk_create
hits the DB once no matter how many objects, except in SQLite (In SQLite it's about 999 per query.). How many objects can be created in a single query can be specified through the parameterbatch_size
.
注意:
- save() will not be called, and the related signals will not be sent.
- does not work with m2m relationships.