【问题标题】:fastest way of inserting data into a table将数据插入表中的最快方法
【发布时间】:2017-08-15 18:53:52
【问题描述】:

我有一个 Postgres 数据库,我在表中插入了一些数据。由于 Internet 连接问题,无法写入某些数据。我尝试写入数据库的文件很大(大约 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()

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

最快的方法是什么?

【问题讨论】:

  • id 是连续的,没有间隔吗?
  • 不幸的是,我不确定。数据是匿名的,row_id 是数据的一部分。我想说是的,但不幸的是,它们不按顺序...

标签: postgresql insert


【解决方案1】:

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

您可以使用最新版本的 PostgreSQL

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

【讨论】:

  • 谢谢迪米特里。我第一次尝试使用COPY,但我那糟糕的无线一直掉线,不得不放弃这个想法。这就是为什么我必须将文件拆分成更小的块,然后从这些小块中的每一个提交批次...
  • 我确实浏览了你的博客。非常令人印象深刻的想法。我会在需要时尝试合并它们。
  • 我刚刚删除了整个表并开始了另一个批量上传。只是现在,我将保存未提交到表中的数据,以便我知道哪些是坏的。
  • 如果您需要使用 COPY 并对不良数据进行分类,请参阅 pgloader,它完全实现了这一点。
  • 谢谢!这看起来像我要找的东西!
【解决方案2】:

我可以提供一个解决方法吗? ?

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

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

【讨论】:

  • 我上传了整个文件,最初将文件拆分为更小的文件。但是,我没有记录插入数据时出现问题的值。所以这就是我所坚持的。我有点想删除表格并重新创建整个东西......
  • 我希望有人能告诉我一些很酷的方法来做到这一点,而不是重新创建整个表格......
  • 我感受到你的痛苦,去过很多次。有时更容易将数据放到您想要的位置,然后再进行清理。
猜你喜欢
  • 1970-01-01
  • 2016-08-12
  • 2021-10-30
  • 2012-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-28
相关资源
最近更新 更多