插入多行时 commit() 的最佳实践

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 进行 WRITE 与 mysql 将所有内容存储在其缓存中然后发送 commit() - write 命令之间的区别。
  • 这样做的性能提升/缺点是什么?
  • 您是否遵守任何约定/最佳实践或实践?为什么?

谢谢!

O. *_*nes 3

你已经表现出了两种极端的立场。

一种是仅在大量插入之后才提交。另一种是在每一行之后提交。

这两者的性能都很差。第一个是不好的,因为 MySQL 创建了一个大事务,然后最后必须提交整个事务。这需要大量 RAM 或临时空间。第二个很糟糕,因为它提交了许多微小的事务。

执行这种批量插入的最佳执行方法是每千行左右提交一次。但这只是比其他方案更难编程一点。根据我的经验,每一千行左右提交一次比其他方法快几倍,因此少量的额外复杂性是值得的。

执行此类批量加载的另一种快速(但脆弱)方法是使用LOAD DATA INFILE,您可以在此处阅读有关该方法的信息: https: //dev.mysql.com/doc/refman/5.6/en/load-data.html

megarow 提交有一个小变化:MySQL 连接可以设置自动提交模式。在这种情况下,您的第一个示例与第二个示例等效。默认情况下,该模式在 python 连接器中处于禁用状态。