django - 随着执行更多插入,Django 应用程序中的数据库插入逐渐变慢

标签 django python-3.x postgresql performance django-rest-framework

我正在使用 Django ORM bulk_create() 向 Postgresql 数据库插入大量行。我大致有以下代码:

entries = []
start = time()
for i, row in enumerate(initial_data_list):
    serializer = serializer_class(data=row, **kwargs)
    serializer.is_valid(raise_exception=True)
    entries.append(MyModel(**serializer.initial_data))
    if i % 1000 == 0:
        MyModel.objects.bulk_create(entries)
        end = time()
        _logger.info('processed %d inserts... (%d seconds per batch)' % (i, end-start))
        start = time()
        entries = []

测量的执行时间:

processed 1000 inserts... (16 seconds per batch)
processed 2000 inserts... (16 seconds per batch)
processed 3000 inserts... (17 seconds per batch)
processed 4000 inserts... (18 seconds per batch)
processed 5000 inserts... (18 seconds per batch)
processed 6000 inserts... (18 seconds per batch)
processed 7000 inserts... (19 seconds per batch)
processed 8000 inserts... (19 seconds per batch)
processed 9000 inserts... (20 seconds per batch)

等,随着插入次数的增加,时间会不断增加。请求在使用 Django 设置 DATABASES['default']['ATOMIC_REQUESTS'] = True 的事务内运行,但是,将其关闭似乎没有任何效果。 DEBUG 模式已关闭。

一些观察:

  • 请求完成后,我执行了一个相同的请求,测量的时间看起来几乎相同:从相当低的开始,然后从那里开始增长。请求之间没有进程重启。

  • 无论我是使用 serializer.save() 还是 bulk_create() 进行单独插入,效果都是一样的。

  • bulk_create() 行本身的执行时间基本保持不变,略多于半秒。

  • 如果我完全删除插入,循环将在恒定时间执行,这表明数据库连接层中发生了一些事情,随着插入数量的增加,这会减慢整个过程...

  • 在执行期间,Python 进程的内存消耗在达到第一个 bulk_create() 后几乎保持不变,Postgres 进程内存也是如此,因此这看起来不是问题所在。

发生了什么使插入物生长变慢?由于新请求再次快速启动(无需重新启动进程),我可以在请求期间执行某种清理以恢复速度吗?

最佳答案

我发现唯一可行的解​​决方案是在 settings.py 中禁用 ATOMIC_REQUESTS,这允许我在请求期间不时调用 db.connection.close() 和 db.connection.connect() 以保持执行生长时间。

关于django - 随着执行更多插入,Django 应用程序中的数据库插入逐渐变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49880358/

相关文章:

python - 在 django cms 中以多种语言提供页面的最佳方法

python - 排除优先级较低的重复元素 (Django)

python - 如何制作 pip 安装包数据(配置文件)?

PostgreSQL "tuple already updated by self"

sql - 如何使用两个表中的数据建立关系?

django - 在 Django 管理员中,是否可以根据组将模型分成子模型?

python - 如何使用 django 和 rest 框架更新用户数据?

Python 2+3 兼容代码 : Should I avoid six?

python - 迭代巨大的 XML 文件并获取值?

java - 如何级联删除@OneToOne?