我有一个 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 使用自动提交模式,因此每个 查询都会导致提交。
就性能而言,事务并不是 Elixir 。您仍在执行 100 次查询和 100 次数据库往返。即使您的数据库在同一个系统上运行,这也需要一些时间。这就是 bulk_create
发挥作用的地方。它执行单个查询以一次插入所有数据。您刚刚为自己节省了 99 次数据库往返。这比事务引起的任何加速都重要得多。
关于多条记录的 Django CRUD 操作 - transaction.atomic 与 bulk_create,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44996049/