Python 带有大容量插入的peewee在sqlite db中的速度非常慢
我正在尝试使用peewee对sqlite数据库进行大规模批量插入。我使用的是Python 带有大容量插入的peewee在sqlite db中的速度非常慢,python,performance,sqlite,database-performance,peewee,Python,Performance,Sqlite,Database Performance,Peewee,我正在尝试使用peewee对sqlite数据库进行大规模批量插入。我使用的是atomic,但性能仍然很差。我将这些行插入到大约2500行的块中,并且由于一次插入大约200行。代码如下: with helper.db.atomic(): for i in range(0,len(expression_samples),step): gtd.GeneExpressionRead.insert_many(expression_samples[i:i+step]).execute()
atomic
,但性能仍然很差。我将这些行插入到大约2500行的块中,并且由于一次插入大约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\u samples
是一个字典列表,其中包含GeneExpressionRead
模型的相应字段。我对这个循环进行了计时,执行这个循环需要2-8秒。我有数百万行要插入,现在编写代码的方式可能需要2天才能完成。根据,为了提高性能,我设置了几个pragma。这也没有真正改变我的表现。最后,如所示,应该可以非常快地插入许多行(0.3364秒内插入50000行),但作者似乎也使用了原始sql代码来获得这种性能。有没有人能够使用peewee方法进行如此高性能的插入
编辑:没有意识到peewee的github页面上的测试是针对
MySQL
插入的。可能适用于也可能不适用于这种情况。在所有使用原子的代码作为上下文管理器出现的文档中,它都被用作函数。由于听起来您似乎从未看到代码通过
块退出,因此您可能没有看到关于没有\uuuuu退出
方法的错误
你能用helper.db.atomic()试试:
atomic()
正在启动事务。如果没有开放式事务,插入速度会慢得多,因为每次写入都必须进行一些昂贵的簿记,而不是只在开始和结束时进行
编辑
由于开始问题的代码已更改,我可以了解有关您要插入的表的更多信息吗?它大吗?有多少个指数
由于这是SQLite,您只是在写入一个文件,但您知道该文件是在本地磁盘上还是在网络安装的驱动器上吗?我遇到过这样的问题,因为我试图插入NFS上的数据库。Mobius试图在评论中提供帮助,但其中有很多错误信息
- 创建表时,Peewee为外键创建索引。当前支持的所有数据库引擎都会发生这种情况
- 打开外键PRAGMA会让事情变慢,为什么不是这样呢
- 为了获得最佳性能,不要在要批量加载到的表上创建任何索引。加载数据,然后创建索引。对于数据库来说,这要少得多
- 正如您所指出的,禁用批量加载的自动增量会加快速度
其他资料:
- 使用PRAGMA journal_mode=wal李>
- 使用PRAGMA synchronous=0李>
- 使用PRAGMA locking_mode=EXCLUSIVE李>
这些是加载一组数据的一些好设置。有关更多信息,请查看sqlite文档:
不确定您对helper.db.atomic()所说的是什么意思:
。这就是我的代码中的内容,也在问题中陈述过。哦,我现在明白了。缺少的()
是一个打字错误。正在修复。请查看我编辑的内容。现在已经排除了潜在的琐碎问题,我需要开始更多地了解您的数据库模式。您正在为RNA序列数据创建数据库吗?GeneExpressionRead听起来像FastQ或SAM条目。是的,它是RNA seq。数据已经被处理了,我只是插入了基因读取的INT。为每行插入的其他数据是基因标记、组织和样本的外键。数据库是硬盘上的文件,而不是网络驱动器。外键是否已打开?外键列和它引用的另一个表上的列是否有索引?是的,经过多次搜索后,这几乎就是我所做的。谢谢你的帮助!