我有一个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()
即使对于前几行数据,检查主键是否存在需要花费大量时间。
这样做的最快方法是什么?
答案 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
或类似的东西将文件拆分成较小的文件。然后分别为每个执行复制命令。