使用 COPY 通过 R 加速 100 万行以上的 INSERT 到 Postgres?
Speed up INSERT of 1 million+ rows into Postgres via R using COPY?
我想 bulk-INSERT/UPSERT 使用 R 向 postgreSQL 数据库中插入大量行。为此,我正在使用 R 准备一个多行插入字符串。
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
what causes large inserts to slow down
@Erwin B运行dstetter 和@Craig Ringer 的回答特别有帮助。通过删除索引并遵循其他一些建议,我能够大大加快速度。
然而,我很难实施另一个听起来很有希望的建议: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
而无需将数据写入文件。数据确实适合内存,既然它已经在内存中,为什么要写入磁盘?
我分别在 OS X 上使用 PostgreSQL 9.5,在 RHEL 上使用 9.5。
RPostgreSQL 有一个 "CopyInDataframe" 函数,它看起来应该做你想做的事:
install.packages("RPostgreSQL")
library(RPostgreSQL)
con <- dbConnect(PostgreSQL(), user="...", password="...", dbname="...", host="...")
dbSendQuery(con, "copy foo from stdin")
postgresqlCopyInDataframe(con, df)
其中 table foo
与数据框 df
具有相同的列
我想 bulk-INSERT/UPSERT 使用 R 向 postgreSQL 数据库中插入大量行。为此,我正在使用 R 准备一个多行插入字符串。
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
what causes large inserts to slow down
@Erwin B运行dstetter 和@Craig Ringer 的回答特别有帮助。通过删除索引并遵循其他一些建议,我能够大大加快速度。
然而,我很难实施另一个听起来很有希望的建议: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
而无需将数据写入文件。数据确实适合内存,既然它已经在内存中,为什么要写入磁盘?
我分别在 OS X 上使用 PostgreSQL 9.5,在 RHEL 上使用 9.5。
RPostgreSQL 有一个 "CopyInDataframe" 函数,它看起来应该做你想做的事:
install.packages("RPostgreSQL")
library(RPostgreSQL)
con <- dbConnect(PostgreSQL(), user="...", password="...", dbname="...", host="...")
dbSendQuery(con, "copy foo from stdin")
postgresqlCopyInDataframe(con, df)
其中 table foo
与数据框 df