为啥 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 需要这么长时间才能循环运行,我该如何加快速度?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个查询需要这么长时间?

为啥这个 tensorflow 训练需要这么长时间?

为啥在 VCC 2003 中编译需要这么长时间?

为啥'withColumn'在pyspark中需要这么长时间?

为啥 BigQuery API 调用需要这么长时间?

为啥我的 mysql 简单外连接需要这么长时间?