为啥 psycopg2 INSERT 需要这么长时间才能循环运行,我该如何加快速度?
Posted
技术标签:
【中文标题】为啥 psycopg2 INSERT 需要这么长时间才能循环运行,我该如何加快速度?【英文标题】:Why is psycopg2 INSERT taking so long to run in a loop and how do I speed it up?为什么 psycopg2 INSERT 需要这么长时间才能循环运行,我该如何加快速度? 【发布时间】:2019-08-02 16:14:06 【问题描述】:我正在尝试在 for 循环中使用 psycopg2 INSERT 将 Pandas 数据帧中的 (source_lat, source_long,destination_lat,destination_long) 行插入到 PostgreSQL 表 (gmaps) 中。该表有一个完整性约束,可防止插入重复的(source_lat、source_long、destination_lat、destination_long)行,因此我使用 try except 块捕获任何重复项。我的代码如下。
我正在遍历数据帧中的每一行(大约 100000 行)并在每一行上调用 cursor.execute(INSERT),看看是否会引发完整性错误,如果没有,我会在 gmaps 中插入该行桌子。
但是,这段代码需要很长时间才能运行 - 我怎样才能加快它的速度?我不确定开销在哪里?谢谢!
Ele 是一个包含 (source_lat, source_long,destination_lat,destination_long) 的元组
for ele in coordinates:
#Inserts new row to table
try:
cursor.execute('INSERT INTO gmaps (source_latitude, source_longitude, destination_latitude, destination_longitude) VALUES (%s, %s, %s, %s)', (ele[0], ele[1], ele[2], ele[3])))
except psycopg2.IntegrityError:
conn.rollback()
else:
conn.commit()
【问题讨论】:
不是代码而是数据库拒绝了这个动作。直接往数据库中插入值可以试试看是否快。 执行 100000 个单独的 INSERT 语句会很慢。没办法。 【参考方案1】:有多种选项可以加快插入批量数据的速度。
1.) commit()
循环结束后:
for ele in coordinates:
cursor.execute('INSERT INTO gmaps (source_latitude, source_longitude, destination_latitude, destination_longitude) VALUES (%s, %s, %s, %s)', (ele[0], ele[1], ele[2], ele[3])))
conn.commit()
2.) 使用 psycopg2 的 fast execution helpers,例如 execute_batch() or execute_values()
。
3.) 使用mogrify()
的字符串集中:
dataText = ','.join(cur.mogrify('(%s,%s,%s,%s)', row) for ele in coordinates)
cur.execute('INSERT INTO gmaps VALUES ' + dataText)
cur.commit()
有关INSERT
执行速度的详细比较,请查看this 基准测试。
【讨论】:
以上是关于为啥 psycopg2 INSERT 需要这么长时间才能循环运行,我该如何加快速度?的主要内容,如果未能解决你的问题,请参考以下文章