使用Python / MySQL插入约2000万行的最佳方法

时间:2015-06-11 14:23:44

标签: python mysql

我需要将包含~20M对象的defaultdict对象存储到数据库中。字典将字符串映射到字符串,因此该表有两列,没有主键,因为它是稍后构造的。

我尝试过的事情:

  • executemany,传入字典中的键和值集。当值的数量<1时,效果很好。 〜1M。
  • 执行单个陈述。工作,但很慢。
  • 使用交易

    con = sqlutils.getconnection()
    cur = con.cursor()
    print len(self.table)
    
    cur.execute("SET FOREIGN_KEY_CHECKS = 0;")
    cur.execute("SET UNIQUE_CHECKS = 0;")
    cur.execute("SET AUTOCOMMIT = 0;")
    i = 0
    for k in self.table:
        cur.execute("INSERT INTO " + sqlutils.gettablename(self.sequence) + " (key, matches) values (%s, %s);", (k, str(self.hashtable[k])))
        i += 1
        if i % 10000 == 0:
            print i
    #cur.executemany("INSERT INTO " + sqlutils.gettablename(self.sequence) + " (key, matches) values (%s, %s)", [(k, str(self.table[k])) for k in self.table])
    
    cur.execute("SET UNIQUE_CHECKS = 1;")
    cur.execute("SET FOREIGN_KEY_CHECKS = 1;")
    cur.execute("COMMIT")
    con.commit()
    cur.close()
    con.close()
    
    print "Finished", self.sequence, "in %.3f sec" % (time.time() - t)
    

这是最近从SQLite到MySQL的转换。奇怪的是,当我使用SQLite(30秒在SQLite中插入3M行,在MySQL中插入480秒)时,我的性能会提高得多。不幸的是,MySQL是必需的,因为该项目将在未来扩大规模。

-

修改

使用LOAD DATA INFILE就像魅力一样。感谢所有帮助过的人!插入3.2M行需要大约25秒。

2 个答案:

答案 0 :(得分:0)

MySQL可以使用一个查询插入多个值:DummyItem

此外,您可以尝试在文件中编写数据并使用旨在以“非常高速”插入的LOAD DATA from Mysql(dixit Mysql)。

我不知道“文件写入”+“MySQL加载数据”是否会比在一个查询中插入多个值更快(或者如果MySQL有限制,则为多个查询)

这取决于您的硬件(使用SSD编写文件“快速”),文件系统配置,MySQL配置等等。因此,您必须测试“prod”环境以查看解决方案是什么最快的。

答案 1 :(得分:0)

插入直接插入,生成一个sql文件(使用{{3}}等)然后将其提取到MySQL,这将为您节省相当多的开销。

注意:如果你避免在循环中重新计算常量值,你仍然会节省一些执行时间,即:

for k in self.table:
    xxx = sqlutils.gettablename(self.sequence)
    do_something_with(xxx, k)

=&GT;

xxx = sqlutils.gettablename(self.sequence)
for k in self.table:
    do_something_with(xxx, k)