我打算使用django的ORM将从约750个文件(每个~250MB)中取出的十亿条记录上传到数据库.目前每个文件需要大约20分钟才能处理,我想知道是否有任何方法可以加速这个过程.
我采取了以下措施:
我还能做些什么来加快速度?以下是我的一些想法:
欢迎任何关于这些项目或任何其他想法的指针:)
我正在开发一个使用MySQLdb访问MySQL数据库的Python程序.在某些情况下,我必须在许多行上运行INSERT或REPLACE命令.我目前正在这样做:
db.execute("REPLACE INTO " + table + " (" + ",".join(cols) + ") VALUES" +
",".join(["(" + ",".join(["%s"] * len(cols)) + ")"] * len(data)),
[row[col] for row in data for col in cols])
Run Code Online (Sandbox Code Playgroud)
它工作正常,但有点尴尬.我想知道我是否可以让它更容易阅读,我发现了executemany命令.我将代码更改为如下所示:
db.executemany("REPLACE INTO " + table + " (" + ",".join(cols) + ") " +
"VALUES(" + ",".join(["%s"] * len(cols)) + ")",
[tuple(row[col] for col in cols) for row in data])
Run Code Online (Sandbox Code Playgroud)
它仍然有效,但运行速度慢了很多.在我的测试中,对于相对较小的数据集(大约100-200行),它运行速度慢了约6倍.对于大数据集(大约13,000行,我期望处理的最大行),它运行速度慢了约50倍.它为什么这样做?
我真的想简化我的代码,但我不希望性能大幅下降.有谁知道如何让它更快?
我使用的是Python 2.7和MySQLdb 1.2.3.我尝试修改setinputsizes函数,但似乎没有做任何事情.我查看了MySQLdb源代码,看起来它不应该做任何事情.
业务:
我遇到了一个问题 - 当使用Django ORM处理大型数据集时,规范的方法是使用每个元素进行操作.但当然这种方式效率很低.所以我决定使用原始SQL.
实质:
我有一个基本代码,它形成SQL查询,更新表的行,并提交它:
from myapp import Model
from django.db import connection, transaction
COUNT = Model.objects.count()
MYDATA = produce_some_differentiated_data() #Creating individual value for each row
cursor = connection.cursor()
str = []
for i in xrange(1, COUNT):
str.append("UPDATE database.table\n"
"SET field_to_modify={}\n"
"WHERE primary_key_field={};\n".format(MYDATA, i))
str = ''.join(str)
cursor.execute(str)
transaction.commit_unless_managed() #This cause exception
Run Code Online (Sandbox Code Playgroud)
在最后一个声明中我得到了这个,即使SIZE它很小:
_mysql_exceptions.ProgrammingError: (2014, "Commands out of sync; you can't run this command now")
Run Code Online (Sandbox Code Playgroud)
也许Django不允许一次执行多个SQL查询?
ps在提交之前关闭游标有助于避免异常,但这是正确的吗?
我的期望:
我正在为批量操作寻找所有可能的可靠解决方案(最好是在Django内部).我不关心它是ORM还是原始SQL,我会支持上面粘贴的代码,如果我能避免错误的话.如果没有解决方案,至少,只是为了好奇,才能知道这个例外的原因.
除了答案我还学到了什么:
在Django 1.4中引入bulk_create了高效的多重INSERT操作
django ×2
orm ×2
python ×2
sql ×2
bulk ×1
bulkinsert ×1
mysql ×1
optimization ×1
performance ×1