Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在postgresql中加速批量更新_Python_Postgresql_Python 3.x_Sqlalchemy - Fatal编程技术网

Python 如何在postgresql中加速批量更新

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

当我处理100000条左右的记录时,得到了一个运行速度非常快的脚本(大约20秒处理30000条记录)。脚本从postgresql数据库中获取记录,对其进行处理,然后在数据库中标记这些记录已被处理

问题是我现在已经将脚本指向了一个有5000万条记录的数据库,而现在10000条记录大约需要160秒!这是非常缓慢的

我能做些什么来加速我的更新吗

我的python和SQLAlchemy核心代码是:

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包括在内。欢迎提出更多建议