我正在使用Python中的MySQLdb模塊來與數據庫交互。我有一個情況,就是有一個非常大的列表(數以萬計的元素),我需要將其作爲行插入到表中。Python + MySQL - 批量插入
我現在的解決方案是生成一個大的INSERT
語句作爲字符串並執行它。
有沒有更聰明的方法?
我正在使用Python中的MySQLdb模塊來與數據庫交互。我有一個情況,就是有一個非常大的列表(數以萬計的元素),我需要將其作爲行插入到表中。Python + MySQL - 批量插入
我現在的解決方案是生成一個大的INSERT
語句作爲字符串並執行它。
有沒有更聰明的方法?
有一個更聰明的方法。
大容量插入的問題是默認情況下autocommit is enabled因此導致每個insert
語句在下一次插入啓動之前被保存到穩定存儲區。
由於手冊頁註釋:
默認情況下,MySQL的運行啓用了自動提交 模式。這意味着,當您執行 更新(修改)表時,儘快 ,MySQL 將更新存儲在磁盤上以使其永久爲 。要禁用自動提交模式, 使用下面的語句:
SET autocommit=0;
由 自動提交變量設置爲零,禁用 自動提交模式後,改變 事務安全表(如 那些InnoDB的,BDB或NDBCLUSTER) 不會立即生效。 您必須使用COMMIT將您的 更改存儲到磁盤或ROLLBACK以忽略 的更改。
這是RDBMs系統的一個非常普遍的特性,它假定數據庫完整性是最重要的。它確實使批量插入每個插入的次數爲1s,而不是1ms。製作超大插入語句的替代方法試圖實現這種單次提交有可能重載SQL解析器的風險。
如果你不得不插入非常大量的數據,你爲什麼要試圖將它們全部插入到一個單一的insert
? (這將不必要地在你的內存中加載這個大的insert
字符串,同時也執行它。如果你的數據插入非常大,這不是一個很好的解決方案。)
爲什麼不你在db中爲每個insert
命令添加一行,並使用for...loop
放置所有行,並在最後提交所有更改?
con = mysqldb.connect(
host="localhost",
user="user",
passwd="**",
db="db name"
)
cur = con.cursor()
for data in your_data_list:
cur.execute("data you want to insert: %s" %data)
con.commit()
con.close()
(相信我,這實在是快,但如果你是越來越慢的結果那麼就意味着你的autocommit
必須True
。將它設置爲False
,因爲msw
表示。)
從1.2.0開始,MySQLdb根據DB-API標準(PEP-249)的要求默認禁用自動提交。來源:http://mysql-python.sourceforge.net/FAQ.html – mikewaters
如果你覺得你的插入仍然比他們應該慢,確保也調整你的MySQL服務器設置。在我的情況下,我的'innodb_buffer_pool_size'對於我的交易規模來說太小了,通過提高它,我實現了批量插入+ 40%的加速。請參閱:https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool.html – jlh