【发布时间】:2019-09-18 23:58:22
【问题描述】:
我有一个导入 CSV 的 python 导入脚本。 将 20k 行导入 mysql 数据库大约需要 45 秒。 问题是现在我有一个巨大的文件(400 万行),当它到达文件的 ~200k 行时,导入相同的 20k 行需要大约 200 秒。
我不知道这是数据库问题还是文件本身正在读取...这是我的脚本:
import csv
import mysql.connector
from mysql.connector import Error
import argparse
from itertools import islice
parser = argparse.ArgumentParser()
parser.add_argument('file', type=argparse.FileType('r'))
args = parser.parse_args()
def parseData(row):
sql = """INSERT INTO TABLE
(column1,column2)
VALUES( '%s','%s');""" % (
row['col1'],row['col2'],)
return sql
def dataImport(filename,connection,cursor):
data = csv.DictReader(filename,delimiter=';')
i = 0
for row in data:
sql = parseData(row)
try:
result = cursor.execute(sql)
pass
except Error as e:
pass
if i%20000 == 0:
connection.commit()
i=i+1
def importa(file):
try:
connection = mysql.connector.connect(host=host,
database=db,
user=user,
password=password)
if connection.is_connected():
db_Info = connection.get_server_info()
print("Connected to MySQL Server version ", db_Info)
cursor = connection.cursor()
dataImport(file,connection,cursor)
cursor.close()
except Error as e:
print("Error while connecting to MySQL", e)
if __name__ == "__main__":
importa(args.file)
【问题讨论】:
-
使用
executemany进行 20K 行的单次插入而不是提交 20K 插入语句可能会有所帮助。我不使用 mysql,但我发现类似的方法可以加速 PostgreSQL。执行此操作的代码略超出本页的中间部分。 pynative.com/python-mysql-insert-data-into-database-table -
@Deepstop 感谢您的建议,我会尝试并告诉您
-
@Deepstop 它确实大大提高了我的导入速度(现在 20k 需要 4 秒!),但是对于 ~200k 之后的行,20k 需要大约 2500 秒....有什么想法吗?
-
可能与索引有关?您可以将 TABLE 的架构添加到您的帖子中吗?此外,如果您将每个 200K 块移动到
executemany之前的列表中,那么您可以使用time.time()来确定是慢速的csv文件还是insert,但我怀疑是后者。但是,我是否也可以建议,除非有令人信服的理由,否则停止使用DictReader并仅使用带有数字索引的reader,如果您还没有这样做的话,这应该会减少客户端的一些开销。 -
现在的问题出在数据库上,它滞后于那一千行......有趣的是,当文件开始处理时它并没有滞后,即使表量很大...... ..奇怪....我用时间来衡量交易时间,tks!
标签: python mysql import-csv