2017-08-15 92 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

相關問題