Mar*_*ark 5 mysql transactions database-performance python-3.x
[Situation-Aim]
我们有一个 CSV 格式的数据集,有 100 万行。这些需要导入到mysql 5.6数据库中,带有innodb引擎的表,带有以下列(匹配csv文件):
Column1: bigint(15)
Column2: datetime
要导入这些数据,我们可以使用以下 python 脚本:
#python version: 3.4.3
#mysql connector version: 2.0.4
#Note: this is just a simple example script!
import mysql.connector
import csv
#Set-up db connection
cnx = mysql.connector.connect(user='user', password='secret', database='mydatabase')
cursor = cnx.cursor()
#read/ open csv
reader = csv.reader(open("C:/test.csv", "rt"))
#ignore header
next(reader)
#read CSV and send to mysql
for row in reader:
id=row[0]
adate = row[1]
cursor.execute("""INSERT INTO mytable VALUES ('%s','%s')""" % (id,adate))
#commit the query
cnx.commit()
Run Code Online (Sandbox Code Playgroud)
[问题]
当我将 cnx.commit() 放入for循环中时,概念上发生了什么,如下所示:
for row in reader:
id=row[0]
adate = row[1]
cursor.execute("""INSERT INTO mytable VALUES ('%s','%s')""" % (id,adate))
cnx.commit()
Run Code Online (Sandbox Code Playgroud)
谢谢!
你已经表现出了两种极端的立场。
一种是仅在大量插入之后才提交。另一种是在每一行之后提交。
这两者的性能都很差。第一个是不好的,因为 MySQL 创建了一个大事务,然后最后必须提交整个事务。这需要大量 RAM 或临时空间。第二个很糟糕,因为它提交了许多微小的事务。
执行这种批量插入的最佳执行方法是每千行左右提交一次。但这只是比其他方案更难编程一点。根据我的经验,每一千行左右提交一次比其他方法快几倍,因此少量的额外复杂性是值得的。
执行此类批量加载的另一种快速(但脆弱)方法是使用LOAD DATA INFILE
,您可以在此处阅读有关该方法的信息: https: //dev.mysql.com/doc/refman/5.6/en/load-data.html
megarow 提交有一个小变化:MySQL 连接可以设置自动提交模式。在这种情况下,您的第一个示例与第二个示例等效。默认情况下,该模式在 python 连接器中处于禁用状态。