我有一个PostgreSQL数据库,我需要根据Python中执行的一些计算来更新特定的列。这是运行非常慢,似乎慢下来的时间越长的代码运行(它通过了约3%的行在12个小时)。
我不认为我是基于Windows任务管理器的资源受限。我有RAM和CPU可用。磁盘活动率为100%,但执行速度低于NVME读/写速度。
该数据库有大约16亿行。id
是主键。我使用psycopg 2与它交互,如下所示:
import psycopg2
def retrieve_raw_content_batch(batch_size):
with db_connect() as conn:
with conn.cursor('testit') as cursor:
cursor.execute("SELECT id, columnoftext FROM table;")
while True:
rows = cursor.fetchmany(batch_size)
if not rows:
break
yield rows
def update_database(upload_list):
with db_connect() as conn:
with conn.cursor() as cursor:
update_query = "UPDATE table SET col1 = %s, col2 = %s WHERE id = %s"
psycopg2.extras.execute_batch(cursor, update_query, upload_list)
def do_stuff(row_batch):
for rows in row_batch:
upload_list = []
for row in rows:
#calculate to get id, col1, col2
upload_list.append((id, col1, col2))
update_database(upload_list)
def main(batch_size):
rows_batch = retrieve_raw_content_batch(batch_size)
do_stuff(rows_batch)
我试图通过将max_wal_size
增加到10 GB来修改postgresql.conf文件,但我对Postgres相对较陌生。我不知道如何优化我的数据库配置,或者这是否是问题所在。
我还想知道用COPY
创建一个新表并在后面使用JOIN
,而不是每行单独使用UPDATE
是否更有意义。
1条答案
按热度按时间vh0rcniy1#
它花了这么长时间的原因是你对每一行都使用了UPDATE,这意味着你有16亿个事务-这将永远花不完。
如果将UPDATE拆分为多个批,则可以大大减少事务的数量。postgres中最安全和最有效的方法是创建一个临时表来批量更新和传输。解决方案相对简单,只要它适合您的使用情况:
您必须指定
batch_size
等,可能还需要进行一些小的修改,但这是通用结构