我有一个 Django 1.10 模型和一个简单的模型:
我有一个简单的 REST 端点,专为测试目的而设计:
@api_view(['POST'])
@transaction.atomic
def r_test(request):
for record in request.data:
serializer = TestSerializer(data = record)
if serializer.is_valid():
serializer.save()
。对于一条 100 条记录,执行需要 9 秒(太慢(。
如果我按以下方式重写它,它会立即执行。
@api_view(['POST'])
def r_test(request):
obj_list = []
for record in request.data:
obj = Test(field1 = record['field1'])
obj_list.append(obj)
Test.objects.bulk_create(obj_list)
困扰我的是,我已经在许多来源中读到将函数包装到事务中(我通过添加装饰器@transaction.atomic
(将在多个操作的情况下显着改善插入操作。但我现在看不到这一点。
所以问题是,只有bulk_create((为插入大数据提供了超快的速度,还是我在transaction.atomic
做错了什么?
更新:此外,我ATOMIC_REQUESTS
设置中设置为True
。顺便说一句,可能是设置有问题吗?比如说,Debug = True 阻碍了 Django 在单个事务中执行查询?
更新 2我已经尝试了两种方式使用装饰器和将 for 循环包装在with transaction.atomic():
中.而且我仍然只观察到即时执行bulk_create()
更新 3.我的数据库是 MySQL
事务通常会加快插入过程。由于您已经由于ATOMIC_REQUESTS = True
而处于事务中,因此在使用@transaction.atomic()
时不会注意到差异。事务更快的主要原因是提交需要时间。在没有事务的情况下,Django 使用自动提交模式,因此每个查询都会导致提交。
在性能方面,交易不是灵丹妙药。您仍在执行 100 次查询和 100 次数据库往返。即使您的数据库在同一系统上运行,也需要一些时间。这就是bulk_create
发挥作用的地方。它执行单个查询以一次插入所有数据。您刚刚为自己节省了 99 次数据库往返。这比交易引起的任何加速都重要得多。
djangorestframework,对吧?我认为你应该先改进你的 api 功能:
def r_test(request):
serializer = TestSerializer(data=request.data, many=True)
if serializer.is_valid():
serializer.save()
再试一次。