将数据插入表格的最快方法

时间:2017-08-15 08:39:14

标签: postgresql insert

我有一个Postgres数据库,我已经在表格中插入了一些数据。由于互联网连接问题,一些数据无法写入。我试图写入数据库的文件很大(大约330712484行 - 即使ws -l命令需要一段时间才能写入完整。

现在,列row_id是(整数)主键,并且已经编入索引。由于某些行无法插入表中,因此我想将这些特定行插入表中。 (我估计只有大约1.8%的数据没有插入表中......)作为开头,我试图看到主键是在数据库中,如下所示:

conn      = psycopg2.connect(connector)
cur       = conn.cursor()

with open(fileName) as f:

    header = f.readline().strip()
    header = list(csv.reader([header]))[0]
    print(header)
    for i, l in enumerate(f):
        if i>10: break
        print(l.strip())

        row_id = l.split(',')[0]

        query = 'select * from raw_data.chartevents where row_id={}'.format(row_id)
        cur.execute(query)
        print(cur.fetchall())

cur.close()
conn.close()

即使对于前几行数据,检查主键是否存在需要花费大量时间。

这样做的最快方法是什么?

2 个答案:

答案 0 :(得分:2)

在PostgreSQL中插入数据的最快方法是使用COPY协议,该协议在psycopg2中实现。 COPY不允许您检查目标ID是否已存在。最好的选择是将您的文件内容复制到临时表中,然后插入或更新,就像我之前在Batch Update博客上写的http://tapoueh.org文章一样。

使用最新版本的PostgreSQL,您可以使用

INSERT INTO ...
SELECT * FROM copy_target_table
    ON CONFICT (pkey_name) DO NOTHING

答案 1 :(得分:0)

我可以提供解决方案吗? ?

将检查插入的每一行的索引,Postgres也会在单个事务中执行整个插入,因此您在写入之前有效地将所有这些数据存储到磁盘。

我可以建议你删除索引以避免这种速度减慢,然后使用head -n [int] > newfile或类似的东西将文件拆分成较小的文件。然后分别为每个执行复制命令。