使用COPY通过R加速将1百万+行插入Postgres?

时间:2017-04-11 15:47:20

标签: r postgresql insert copy postgresql-performance

我想使用R批量INSERT / UPSERT大量的行到postgreSQL数据库。为了做到这一点,我正在准备一个使用R的多行INSERT字符串。

 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)

可以找到整个功能here。令人惊讶的是(对我来说)我了解到UPDATE部分不是问题。我把它留了出去并再次运行查询,但速度并不快。插入一百万+记录似乎是这里的问题。

我做了一些研究,发现了一些信息:

bulk inserts

bulk inserts II

what causes large inserts to slow down

来自@Erwin Brandstetter和@Craig Ringer的回答特别有帮助。通过删除索引并遵循其他一些建议,我能够加快速度。

然而,我努力实施另一个听起来很有希望的建议:COPY。问题是我无法从内部完成它。

以下适用于我:

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。

1 个答案:

答案 0 :(得分:5)

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

的列相同