gpt4 book ai didi

django - 并行线程不会增加具有 Django 性能的多个数据库插入

转载 作者:行者123 更新时间:2023-11-29 12:37:04 24 4
gpt4 key购买 nike

我正在使用 Python 和 Django(使用 CLI,所以根本没有 Web 服务器)对 PostgreSQL 数据库执行成千上万次插入操作。插入的对象已经在内存中,我从 FIFO 队列中一个一个地弹出它们(使用 Python 的 native https://docs.python.org/2/library/queue.html )

我所做的基本上是:

args1, args2 = queue.get()
m1, _ = Model1.objects.get_or_create(args1)
Model2.objects.create(m1, args2)

我正在考虑一种更快地执行此操作的方法,即生成更多可以并行执行此操作的线程。令我惊讶的是,性能实际上略有下降......我期待与线程数量相关的几乎线性改进......不确定发生了什么......

是否缺少某些特定于数据库的东西,是否有表锁在运行时阻塞线程?还是与每个线程在运行时只能原子地访问单个数据库连接有关?

我在 Debian Jessie 上使用 apt-get 安装了 PostgreSQL (9.3) 和 Django (1.7.7) 的标准配置。我还尝试了 4 个线程,这与我机器上可用的 CPU 数量相同。

最佳答案

这里发生了一些事情。

首先,您正在使用非常高级的 ORM 方法(get_or_createcreate)。这些通常不适合批量操作,因为这样的方法往往会产生大量开销来提供良好的 API,并且还会做额外的工作以防止用户太容易搬起石头砸自己的脚。

其次,您对 queue 的谨慎使用会在多个方面适得其反:

  • 由于 django 在 autocommit mode 中运行默认情况下,每个数据库操作都在其自己的事务中执行。由于这是一个相对昂贵的操作,这也会导致不必要的开销。
  • 单独插入每个对象也会导致数据库和 Django 之间的来回通信更多,这会再次产生开销,从而降低速度。

第三,使用多线程甚至更慢的原因是 python 有一个 GIL(全局解释器锁)。这可以防止多个线程同时执行 Python 代码。网络上有很多关于 GIL 的原因和方式的资料,以及在什么情况下可以做什么来缓解它。有个不错的summary by Dave Beazly如果您有兴趣了解更多有关 GIL 的信息,可以帮助您入门。

此外,我通常建议不要使用任何语言从多个线程执行大量插入,因为 - 根据您的数据库和数据模型 - 这也可能由于可能需要锁定而导致数据库内部速度变慢。

现在您的问题有很多解决方案,但我建议您从一个简单的开始:Django 实际上提供了一个方便的低级接口(interface)来批量创建模型,称为 bulk_create() 很合适。 .我建议删除所有花哨的队列和线程代码,并尽可能直接地使用此接口(interface)处理您已有的数据。

如果这对您的情况来说还不够,一种可能的替代方法是从数据生成一个 INSERT INTO 语句并直接在数据库上执行它。

关于django - 并行线程不会增加具有 Django 性能的多个数据库插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31062124/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com