在许多大数据记录中增加Django的INSERT性能

时间:2015-08-12 23:33:23

标签: python mysql django database insert

所以我一直试图解决这个问题一段时间,尽管在StackOverflow和许多谷歌搜索上发现了很多建议和提示,但似乎无法找到加快Django插入性能的方法。

所以基本上我需要通过Django将大量数据记录(~2百万)插入我的MySQL数据库,每个记录条目高达180KB。我已经将我的测试缩减到2,000个插入但仍然无法将运行时间降低到合理的数量。 2,000个插入目前大约需要120秒。

所以我尝试了以下所有内容(以及每种内容的多种组合)无济于事:

  • “Classic”Django ORM创建模型和.save()
  • 单笔交易(transaction.atomic())
  • Bulk_create
  • 原始SQL INSERT for for循环
  • 原始SQL“executemany”(在一个查询中插入多个值)
  • 设置SQL属性,例如“SET FOREIGN_KEY_CHECKS = 0”
  • SQL BEGIN ... COMMIT
  • 将质量插入物分成较小批次

如果我忘记列出某些内容,请道歉,但此时我只是尝试了很多不同的事情,我甚至无法跟踪ahah。

非常感谢这方面的一些帮助,可以加快那些可能不得不使用Django数据库插入执行类似任务的人的性能。

如果我遗漏了任何必要的信息,请告诉我!

3 个答案:

答案 0 :(得分:1)

这实际上是django的范围。 Django只是将你的python转换为tbody语句。对于django层上的大多数性能,完全跳过它(通过执行sql raw)可能是最好的,即使python处理与sql-database的IO相比非常快。

您应该专注于数据库。我是一个postgres人,所以我不知道mysql有什么配置选项,但可能有一些微调可用。
如果你已经这样做并且仍然没有增加,你应该考虑在RAID 0中使用SSD,SSD,甚至在内存中使用db,以跳过IO次。 分片也可能是一个解决方案 - 分割任务并同时执行它们。

如果插入不是时间关键的,即可以随时进行,但不应阻止页面加载,我推荐芹菜。 只要有时间,您就可以将任务排队等待 - 异步。

答案 1 :(得分:0)

您还可以尝试删除表上的任何索引(以及任何其他约束),在插入后重新创建索引和约束。

更新索引和检查约束可能会减慢每次插入的速度。

答案 2 :(得分:0)

所以我发现编辑mysql /etc/mysql/my.cnf文件并配置一些InnoDB设置可以显着提高性能。

我设置:

  • innodb_buffer_pool_size = 9000M 75%的系统内存
  • innodb_log_file_size = 2000M 上述值的20%-30%

重新启动了mysql服务器,这减少了50个插入,从~3秒到~0.8秒。还不错!

现在我注意到,对于大数据量,插入内容会逐渐延长。 50次插入在约0.8秒开始,但在100次左右后,平均值达到1.4秒并继续增加。

如果已解决则会报告。