2017-04-11 216 views
1

我想批量INSERT/UPSERT適度大量行使用R.爲了做到這一點,我準備用R.使用COPY加速將100萬行的INSERT插入到Postgres中?

query <- sprintf("BEGIN; 
         CREATE TEMPORARY TABLE 
         md_updates(ts_key varchar, meta_data hstore) ON COMMIT DROP; 

         INSERT INTO md_updates(ts_key, meta_data) VALUES %s; 
         LOCK TABLE %s.meta_data_unlocalized IN EXCLUSIVE MODE; 

         UPDATE %s.meta_data_unlocalized 
         SET meta_data = md_updates.meta_data 
         FROM md_updates 
         WHERE md_updates.ts_key = %s.meta_data_unlocalized.ts_key; 
         COMMIT;", md_values, schema, schema, schema, schema) 

DBI::dbGetQuery(con,query) 

整個一個多行INSERT串PostgreSQL數據庫功能可以找到here。令人驚訝的是(對我來說)我瞭解到UPDATE部分不是問題。我離開它並再次運行查詢,速度並不快。插入一百萬條記錄似乎是這裏的問題。

我做了一些研究,發現相當長的一段信息:

bulk inserts

bulk inserts II

what causes large inserts to slow down

從@Erwin Brandstetter修改和@Craig林格答案是特別有幫助。我能夠通過放棄索引和其他一些建議來加快速度。

但是,我努力實施另一個聽起來很有希望的建議:COPY。問題是我不能讓它從內部R.

下面的工作做了我:

sql <- sprintf('CREATE TABLE 
      md_updates(ts_key varchar, meta_data hstore); 
      COPY md_updates FROM STDIN;') 


dbGetQuery(sandbox,"COPY md_updates FROM 'test.csv' DELIMITER ';' CSV;") 

但我不能把它從沒有一個額外的.csv文件讀取完成。所以我的問題是:

  • COPY真的在這裏有前途的方法(在多行INSERT我

  • 有沒有使用來自R內部COPY無需將數據寫入到文件的方法嗎? 。數據不適合在內存中,因爲它已經在MEM爲什麼寫入到磁盤?

我在OS X上使用PostgreSQL 9.5和分別RHEL 9.5。

+0

它必須在R' R可以調用'psql'嗎?如果是這樣,請使用'\ COPY'(而不是'COPY') –

+0

@Neil McGuigan是的,得到R. R可以進行任何類型的系統調用,所以psql是一個選項,但是因爲這是一個包的一部分,並且部署到任何地方我不想依賴psql。仍在尋找內部R解決方案。 –

+0

請讓埃裏克從埃裏克回來 - 它看起來很奇怪 –

回答

2

RPostgreSQL具有「CopyInDataframe」功能,看起來像它應該做你想要什麼:

install.packages("RPostgreSQL") 
library(RPostgreSQL) 
con <- dbConnect(PostgreSQL(), user="...", password="...", dbname="...", host="...") 
dbSendQuery(con, "copy foo from stdin") 
postgresqlCopyInDataframe(con, df) 

凡表foo有相同的列數據框df

+0

感謝+1這實際上有效。多年來我一直在使用'RPostgreSQL'包,但沒有搜索這樣的功能。它正是我想要的。將運行幾個基準測試,看看它是否真的加快速度。 –

+1

感謝您的幫助。對於更大的INSERT,它實際上快了6倍。 –

相關問題