2017-08-15 94 views
0

我有一个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() 

即使对于数据的前几排,检查,小号即主键是否存在需要非常多的时间。

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

+0

是IDS顺序没有差距? –

+0

不幸的是我不确定。数据是匿名的,'row_id'是数据的一部分。我想说的是,但不幸的是,他们不是为了... – ssm

回答

2

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

在PostgreSQL的最新版本不够,你可以使用

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

谢谢迪米特里。我曾经使用过“COPY”作为第一次尝试,但是我的低劣无线技术一直在下降,不得不放弃这个想法。这就是为什么我不得不将文件分成更小的块,然后从这些小块中分别提交批次... – ssm

+0

我确实通过了您的博客。非常可观的想法。我会在需要时尝试合并它们。 – ssm

+0

我刚刚删除了整个表格并开始另一批次上传。直到现在,我才会保存没有提交给表格的数据,所以我知道哪些数据不好。 – ssm

0

我可以提供解决方法。 ?

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

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

+0

我上传了整个文件,最初将文件分割成更小的文件。但是,我没有记录插入数据时出现问题的值。所以这就是我所坚持的。我有一半的想法,删除表和重新创建整个事情... – ssm

+0

我希望有人能够告诉我一些很酷的方式做到这一点,而不是重新创建整个表... – ssm

+0

我觉得你的痛苦,曾经去过很多次。有时候它更容易将数据提交到你想要的地方,然后再清理它。 – Mokadillion

相关问题