Python 如何在postgresql中加速批量更新
当我处理100000条左右的记录时,得到了一个运行速度非常快的脚本(大约20秒处理30000条记录)。脚本从postgresql数据库中获取记录,对其进行处理,然后在数据库中标记这些记录已被处理 问题是我现在已经将脚本指向了一个有5000万条记录的数据库,而现在10000条记录大约需要160秒!这是非常缓慢的 我能做些什么来加速我的更新吗 我的python和SQLAlchemy核心代码是:Python 如何在postgresql中加速批量更新,python,postgresql,python-3.x,sqlalchemy,Python,Postgresql,Python 3.x,Sqlalchemy,当我处理100000条左右的记录时,得到了一个运行速度非常快的脚本(大约20秒处理30000条记录)。脚本从postgresql数据库中获取记录,对其进行处理,然后在数据库中标记这些记录已被处理 问题是我现在已经将脚本指向了一个有5000万条记录的数据库,而现在10000条记录大约需要160秒!这是非常缓慢的 我能做些什么来加速我的更新吗 我的python和SQLAlchemy核心代码是: def process_records(no_of_records, data) for x in
def process_records(no_of_records, data)
for x in range(no_of_records):
my_data = data[x]
'''process the data, when done, mark as is_processed'''
dict = {}
dict['b_id'] = pid
dict['is_processed'] = is_processed
is_processed_list.append(dict)
CONN = Engine.connect()
trans = CONN.begin()
stmt = mytable.update().where(mytable.c.id == bindparam('b_id')).\
values(is_processed=bindparam('is_processed'))
CONN.execute(stmt, is_processed_list)
trans.commit()
编辑
我分析了我的代码,发现问题不在于这个python循环,甚至不在于大容量插入。我浪费了80多秒的问题是首先选择要处理的数据。一旦我明白了这一点,@Martin的建议,我就加入了一个索引和它的返回火箭速度 您应该检查查询计划器告诉您的内容。在SQL查询前面加上“EXPLAIN”以获取有关Postgresql尝试执行的操作的详细信息。首先,试着选择应该更新的行,看看会发生什么 如果选择部分速度慢(读取),则可以在这种情况下使用索引(mytable.c.id==b_id)将其固定。请注意,在Postgresql中,外键不会为表编制索引 有关解释的详细信息,请参见此处:
如果是编写部分速度慢,您可能需要调整Postgresql的配置。(clippy voice):似乎您正在处理自己事务中的每一行。你考虑过一次在一个事务中处理多行吗?@ScottMarlowe实际上是在进行批量更新。如果仔细检查语法,update语句将出现在for循环之后,即update语句运行
is\u processed\u list
,该列表为每次更新提供大约10000条记录。for循环非常快。以微秒为单位运行。只有批量更新才是永恒的。啊,好的。是的,从你的代码中我看不太清楚。很高兴你找到了真正的问题,你做到了。我假设默认情况下外键是索引的。因此,我在该列上创建了一个索引,select语句现在是微秒。甚至感觉不到它的5000万张唱片!不过,为了进行调优,我有一台16GB的机器,运行8核的ubuntu服务器。我已经编辑了配置,将kernel.shmmax=4294967296、kernel.shmall=1073741824和shared_buffers=3500MB包括在内。欢迎提出更多建议