慢速保存到Django数据库

tex*_*nic 1 python sqlite django performance django-queryset

我创建了一个这样的自定义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)
Run Code Online (Sandbox Code Playgroud)

我已经定时handle()执行了,如果我不这样做需要大约0.02秒,如果我保存则person.save()大约需要0.1秒Person.数据库是sqlite,我相信它应该更快.什么可以解释这种糟糕的表现,我该如何改善它?

Dhi*_*aTN 6

分析:

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()
Run Code Online (Sandbox Code Playgroud)

这个函数将在数据库中命中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)
Run Code Online (Sandbox Code Playgroud)

默认情况下bulk_create,无论有多少个对象都会访问数据库,除了在SQLite中(在SQLite中,每个查询大约999个).可以通过参数指定在单个查询中可以创建多少个对象batch_size.

注意:

  • 不会调用save(),也不会发送相关信号.
  • 不适用于m2m关系.

  • 批量创建是+1的方法 (2认同)