我正在尝试将.csv文件中包含的数据从我的电脑插入到远程服务器。这些值将插入包含3列的表中,即Timestamp
,Value
和TimeseriesID
。我必须一次插入大约3000行,因此我目前正在使用pyodbc
和executemany
。
到目前为止,我的代码如下所示:
with contextlib.closing(pyodbc.connect(connection_string, autocommit=True)) as conn:
with contextlib.closing(conn.cursor()) as cursor:
cursor.fast_executemany = True # new in pyodbc 4.0.19
# Innsert values in the DataTable table
insert_df = df[["Time (UTC)", column]]
insert_df["id"] = timeseriesID
insert_df = insert_df[["id", "Time (UTC)", column]]
sql = "INSERT INTO %s (%s, %s, %s) VALUES (?, ?, ?)" % (
sqltbl_datatable, 'TimeseriesId', 'DateTime', 'Value')
params = [i.tolist() for i in insert_df.values]
cursor.executemany(sql, params)
当我使用pyodbc 4.0.19
时,我将fast_executemany
选项设置为True
,这应该可以加快速度。但是,出于某种原因,当我启用fast_executemany选项时,我没有看到任何重大改进。有没有其他方法可以用来加速我的文件插入?
此外,关于上面显示的代码的性能,我注意到当禁用autocommit=True
选项时,而我在数据末尾包含cursor.commit()
命令的速度明显加快了。是否有任何具体原因导致我不知道这种情况发生?
非常感谢任何帮助:)
答案 0 :(得分:2)
关于您注意到的cursor.commit()
加速:当您使用autocommit=True
时,您要求代码为每个插入执行一个数据库事务。这意味着只有在数据库确认数据存储在磁盘上后,代码才会恢复。在大量cursor.commit()
之后使用INSERT
时,您实际上正在执行一个数据库事务,并且数据在临时存储在RAM中(可能会写入磁盘,但在您指示时不是全部用于完成交易的数据库。)
完成事务的过程通常需要更新磁盘上的表,更新索引,刷新日志,同步副本等,这是昂贵的。这就是为什么你在你描述的两个场景之间观察到这样的加速。
如果以更快的方式运行,请注意,在执行cursor.commit()
之前,您无法100%确定数据是否在数据库中,因此可能需要在出现错误时重新发出查询(任何部分事务将被回滚)。