我有一个数据库表,其中包含唯一的字符串字段和几个整数字段。字符串字段通常为10-100个字符。
每分钟左右我都有以下场景:我收到一个与表的记录结构相对应的2-10万个元组的列表,例如:
[("hello", 3, 4), ("cat", 5, 3), ...]
我需要将所有这些元组插入到表中(假设我确认这些字符串都没有出现在数据库中)。为了澄清,我正在使用InnoDB,并且我有一个自动增量主键用于此表,字符串不是PK。
我的代码当前遍历此列表,因为每个元组都会创建一个具有适当值的Python模块对象,并调用“.save()”,如下所示:
@transaction.commit_on_success
def save_data_elements(input_list):
for (s, i1, i2) in input_list:
entry = DataElement(string=s, number1=i1, number2=i2)
entry.save()
此代码目前是我系统中的性能瓶颈之一,因此我正在寻找优化它的方法。
例如,我可以生成SQL代码,每个代码包含100个元组的INSERT命令(“硬编码”到SQL中)并执行它,但我不知道它是否会改进任何东西。
您是否有任何建议来优化此类流程?
由于
答案 0 :(得分:12)
对于MySQL而言,加载数据的最快方法是使用LOAD DATA INFILE,因此如果您可以将数据转换为期望的格式,那么它可能是将其放入表中的最快方式。 / p>
答案 1 :(得分:11)
您可以使用格式将行写入文件 “field1”,“field2”,..然后使用LOAD DATA加载它们
data = '\n'.join(','.join('"%s"' % field for field in row) for row in data)
f= open('data.txt', 'w')
f.write(data)
f.close()
然后执行:
LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;
答案 2 :(得分:4)
如果你没有LOAD DATA INFILE
提到其他一些建议,那么你可以做的两件事就是:
答案 3 :(得分:4)
如果你能做一个手工INSERT
陈述,那就是我的方式。具有多个值子句的单个INSERT
语句比许多单独的INSERT
语句快得多。
答案 4 :(得分:2)
无论insert方法如何,您都希望使用InnoDB引擎实现最大的读/写并发性。 MyISAM将在插入期间锁定整个表,而InnoDB(在大多数情况下)将仅锁定受影响的行,允许SELECT语句继续。
答案 5 :(得分:1)
您收到的格式是什么?如果是文件,您可以进行某种批量加载:http://www.classes.cs.uchicago.edu/archive/2005/fall/23500-1/mysql-load.html
答案 6 :(得分:1)
这与数据到DB的实际负载无关,但是......
如果提供“数据正在加载......加载将很快完成”,则向用户提供消息类型是一个选项,然后您可以在另一个线程中异步运行INSERT或LOAD DATA。
还有别的东西要考虑。
答案 7 :(得分:1)
我不知道确切的细节,但你可以使用json风格的数据表示并将其用作固定装置或其他东西。我在Douglas Napoleone的Django Video Workshop上看到过类似的东西。观看http://www.linux-magazine.com/online/news/django_video_workshop处的视频。和http://www.linux-magazine.com/online/features/django_reloaded_workshop_part_1。希望这个有所帮助。
希望你能解决它。我刚刚开始学习django,所以我可以指出你的资源。