使用批量插入的peewee非常慢进入sqlite db

时间:2016-05-28 14:46:19

标签: python performance sqlite database-performance peewee

我正在尝试使用peewee对sqlite数据库进行大规模批量插入。我正在使用atomic,但表现仍然很糟糕。我在〜2500行的块中插入行,由于SQL_MAX_VARIABLE_NUMBER我一次插入大约200行。这是代码:

with helper.db.atomic():
   for i in range(0,len(expression_samples),step):
      gtd.GeneExpressionRead.insert_many(expression_samples[i:i+step]).execute()

列表expression_samples是一个字典列表,其中包含GeneExpressionRead模型的相应字段。我已经定时了这个循环,执行时需要2-8秒。我有数百万行要插入,现在我编写代码的方式可能需要2天才能完成。根据{{​​3}},我设置了几个pragma以提高性能。对于我来说,这也没有真正改变任何表现。最后,根据this post,应该可以非常快地插入很多行(在0.3364秒内大约50,000),但似乎作者使用原始sql代码来获得这种性能。有没有人能够使用peewee方法做这么高性能的插入?

编辑:没有意识到peewee的github页面上的测试是针对MySQL插入的。可能适用于这种情况,也可能不适用。

2 个答案:

答案 0 :(得分:5)

Mobius试图在评论中提供帮助,但那里有很多错误信息。

  • Peewee在创建表时为外键创建索引。对于当前支持的所有数据库引擎都会发生这种情况。
  • 打开外键PRAGMA会减慢速度,为什么会这样呢?
  • 为了获得最佳性能,请不要在批量加载的表上创建任何索引。加载数据,然后创建索引。这对数据库来说要少得多。
  • 如您所述,禁用批量加载的自动增量会加快速度。

其他信息:

  • 使用PRAGMA journal_mode = wal;
  • 使用PRAGMA synchronous = 0;
  • 使用PRAGMA locking_mode = EXCLUSIVE;

这些是加载大量数据的一些好设置。查看sqlite文档以获取更多信息:

http://sqlite.org/pragma.html

答案 1 :(得分:-1)

在使用atomic的代码作为上下文管理器出现的所有文档中,它都被用作函数。由于您似乎永远不会看到代码退出 with块,因此您可能没有看到有关没有__exit__方法的错误。

你能试试with helper.db.atomic():吗?

atomic()正在开始交易。如果没有打开的事务,插入会慢得多,因为每次写入都需要进行一些昂贵的簿记,而不是只在开始和结束时。

修改

由于启动问题的代码已更改,我是否可以获得有关您要插入的表格的更多信息?它有多大,有多少指数?

由于这是SQLite,您只是写入文件,但是您知道该文件是在本地磁盘上还是在网络驱动器上?我之所以遇到这样的问题是因为我试图在NFS上插入数据库。