TL; DR: LOAD DATA INFILE
複数のINSERT
よりも1桁高速です ステートメントは、それ自体が単一のINSERT
よりも1桁高速です。 ステートメント。
RからMysqlにデータをインポートするための3つの主要な戦略を以下にベンチマークします。
-
単一の
insert
ステートメント 、質問のように:INSERT INTO test (col1,col2,col3) VALUES (1,2,3)
-
複数の
insert
ステートメント 、次のようにフォーマットされています:INSERT INTO test (col1,col2,col3) VALUES (1,2,3),(4,5,6),(7,8,9)
-
load data infile
ステートメント 、つまり、以前に作成したCSVファイルをmysql
にロードします :LOAD DATA INFILE 'the_dump.csv' INTO TABLE test
RMySQL
を使用しています ここでは、他のmysqlドライバーでも同様の結果が得られるはずです。 SQLテーブルは次のようにインスタンス化されました:
CREATE TABLE `test` (
`col1` double, `col2` double, `col3` double, `col4` double, `col5` double
) ENGINE=MyISAM;
接続とテストデータはR
で作成されました と:
library(RMySQL)
con = dbConnect(MySQL(),
user = 'the_user',
password = 'the_password',
host = '127.0.0.1',
dbname='test')
n_rows = 1000000 # number of tuples
n_cols = 5 # number of fields
dump = matrix(runif(n_rows*n_cols), ncol=n_cols, nrow=n_rows)
colnames(dump) = paste0('col',1:n_cols)
単一のinsert
のベンチマーク ステートメント:
before = Sys.time()
for (i in 1:nrow(dump)) {
query = paste0('INSERT INTO test (',paste0(colnames(dump),collapse = ','),') VALUES (',paste0(dump[i,],collapse = ','),');')
dbExecute(con, query)
}
time_naive = Sys.time() - before
=>これには約4分かかります 私のコンピューターで
複数のinsert
のベンチマーク ステートメント:
before = Sys.time()
chunksize = 10000 # arbitrary chunk size
for (i in 1:ceiling(nrow(dump)/chunksize)) {
query = paste0('INSERT INTO test (',paste0(colnames(dump),collapse = ','),') VALUES ')
vals = NULL
for (j in 1:chunksize) {
k = (i-1)*chunksize+j
if (k <= nrow(dump)) {
vals[j] = paste0('(', paste0(dump[k,],collapse = ','), ')')
}
}
query = paste0(query, paste0(vals,collapse=','))
dbExecute(con, query)
}
time_chunked = Sys.time() - before
=>これには約40秒かかります 私のコンピューターで
ベンチマークload data infile
ステートメント :
before = Sys.time()
write.table(dump, 'the_dump.csv',
row.names = F, col.names=F, sep='\t')
query = "LOAD DATA INFILE 'the_dump.csv' INTO TABLE test"
dbSendStatement(con, query)
time_infile = Sys.time() - before
=>これには約4秒かかります 私のコンピューターで
多くの挿入値を処理するSQLクエリを作成することは、パフォーマンスを向上させる最も簡単な方法です。 LOAD DATA INFILE
への移行 最適な結果につながります。優れたパフォーマンスのヒントは、mysqlドキュメントのこのページにあります 。