python - 如何优化python postgresql查询300万条记录

标签 python postgresql psycopg2 postgresql-performance

我正在使用 python 脚本在 postgresql 中插入或更新大约 3 到 4 百万条数据。请参阅下面的代码。要求是如果新键则插入,或者如果键已存在则用新值更新键。但下面的代码与数据库进行了太多的往返连接,大约需要 35 - 45 分钟才能在数据库中插入 300 万条记录,速度非常慢。如何避免往返连接并以更快的方式插入或更新?

任何帮助将不胜感激。

感谢您提前提供的帮助。

InputFile.txt - 该文件大约有 3 到 4 百万行项目

productKey1 printer1,printerModel1,printerPrice1,printerDesc1|
productKey2 sacnner2,scannerModel2,scannerPrice2,scannerDesc2|
productKey3 mobile3,mobileModel3,mobilePrice3,mobileDesc3|
productKey4 tv4,tvModel4,tvPrice4,tvDescription4|
productKey2 sacnner22,scannerModel22,scannerPrice22,scannerDesc22|

插入.py

def insertProduct(filename, conn):
   seen = set()
   cursor = conn.cursor()
   qi = "INSERT INTO productTable (key, value) VALUES (%s, %s);"
   qu = "UPDATE productTable SET value = CONCAT(value, %s) WHERE key = %s;"

   with open(filename) as f:
     for line in f:
       if line.strip():
         key, value = line.split(' ', 1)
         if key not in seen:
            seen.add(key)
            cursor.execute(qi, (key, value))
         else:
            cursor.execute(qu, (value, key))

         conn.commit()

conn = psycopg2.connect("dbname='productDB' user='myuser' host='localhost'")
insertProduct('InputFile.txt', conn)

最佳答案

批量执行准备好的语句。 http://initd.org/psycopg/docs/extras.html#fast-execution-helpers

import psycopg2, psycopg2.extras
def insertProduct(filename, conn):

    data = []
    with open(filename) as f:
        for line in f:
            line = line.strip()
            if line:
                key, value = line.split(' ', 1)
                data.append((key, value))

    cursor = conn.cursor()
    cursor.execute("""
        prepare upsert (text, text) as
        with i as (
            insert into productTable (key, value)
            select $1, $2
            where not exists (select 1 from productTable where key = $1)
            returning *
        )
        update productTable p
        set value = concat (p.value, $2)
        where p.key = $1 and not exists (select 1 from i)
    """)
    psycopg2.extras.execute_batch(cursor, "execute upsert (%s, %s)", data, page_size=500)
    cursor.execute("deallocate upsert")
    conn.commit()          

conn = psycopg2.connect(database='cpn')
insertProduct('InputFile.txt', conn)

关于python - 如何优化python postgresql查询300万条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47165342/

相关文章:

python - 使用 psycopg2 从 csv 文件动态创建表

javascript - HTML DOM 基本抓取

python - Pandas 选择具有 bool 日期条件的列

sql - 在 postgresql 中加入多列

mysql - 跟踪谁在数据库中收到/未收到帖子的最佳方法?

postgresql - Play/光滑 : SQLTimeoutException: Timeout after 1001ms of waiting for a connection

python - 无法在 fedora 27 上从 python3 导入 psycopg2

python-3.x - 从 SQLAlchemy session 对象获取原始 psycopg2 游标对象

javascript - 单击按钮时出现 Selenium 错误 : . MoveTargetOutOfBoundsException

python - GroupBy 对象,其中条目可以属于多个组