【问题标题】:Insert data into Postgresql from Python从 Python 将数据插入 Postgresql
【发布时间】:2019-03-09 22:24:50
【问题描述】:

≈105 秒每 100 万行插入到具有 2 个索引和 4 列的表上的 Postgresql 本地数据库中是慢还是快?

Python 代码:

import os 
import pandas as pd 
from concurrent.futures import ThreadPoolExecutor, as_completed
from sqlalchemy import create_engine

num =  32473068
batch = 1000000

def main(data):
    engine = create_engine('postgresql://***:****' + host + ':5432/kaggle')
    data.to_sql(con=engine, name=tbl_name, if_exists='append', index=False)

for i in range(0, num, batch):
    data = pd.read_csv(data_path+'app_events.csv', skiprows=i, nrows=batch)
    data.columns = ['event_id', 'app_id', 'is_installed', 'is_active']
    data = data.reset_index(drop=True)
    batchSize = 10000
    batchList = [data.iloc[x:x + batchSize].reset_index(drop=True) for x in range(0, len(data), batchSize)]
    with ThreadPoolExecutor(max_workers=30) as executor:
        future_to_url = {executor.submit(main, d): d for d in batchList}
        for k, future in enumerate(as_completed(future_to_url)):
            url = future_to_url[future]

【问题讨论】:

  • Postgres 有用于导入 CSV 文件的特殊命令 COPY - 没有什么比这更快了。
  • pg_bulkload 实际上更快
  • 除了 @user2189731 关于在引擎实例化的 SQLAlchemy 中启用 use_batch_mode=True 的精彩观点之外,我建议您跳过此任务的多线程。这不太可能提供任何有益的并发性,并且可能会因锁定争用而损失比您获得的更多。

标签: python postgresql concurrent.futures


【解决方案1】:

这也取决于您的硬件。作为参考,我的带有 HDD 的旧 I5 笔记本电脑使用约 300 秒来插入 0.1M 行(大约 200-300 兆字节)。

我从其他类似的问题中了解到,在使用 insert() 命令时将大值拆分为大块可以加快速度。由于您使用的是 Pandas,我认为它已经进行了某些优化。但我建议你做一个快速测试,看看它是否也有帮助。

  • Pandas 实际上使用了非优化的插入命令。请参阅 (to_sql + sqlalchemy + copy from + postgresql engine?)。所以应该使用批量插入或其他方法来提高性能。

  • 当您使用“use_batch_mode=True”参数初始化引擎时,SQLalchemy 1.2 使用批量插入。我在 I5+HDD 笔记本电脑上看到了 100 倍的加速!意思是 0.1M 的记录,原来我花了 300 秒,现在是 3 秒!!如果你的电脑比我的好,我敢打赌你会看到你的 1M 记录的巨大加速。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    相关资源
    最近更新 更多