【发布时间】:2016-02-06 23:58:39
【问题描述】:
我尝试了 3 种不同的方法将多行(超过 500 行)插入到 SQLite 表中。与直觉相反,下面的方法 3 是最快的。我会假设方法 2 是最快的,因为它使用“准备好的”语句句柄。但是我的第三种方法——一次插入 500 行(500 显然是 SQLite 中允许的最大值)——要快得多。
我错过了什么吗?我应该继续使用 500 方法,还是有其他方法?
注意:下面的代码不是我的实际代码,我只是写在这里作为示例,没有经过测试。
use strict;
use warnings;
use DBI;
my $dsn = "DBI:SQLite:dbname=db";
my $dbh = DBI->connect($dsn,"","");
open my $data_file,"<","data.txt"; # 3 integer fields per line
APPROACH_1:
while (<$data_file>) {
my @fields = split "\t";
my $insert = join ",", @fields;
$dbh->do("insert into table values ($insert)";
}
APPROACH_2:
my $sql = "insert into table values (?,?,?)";
my $sth = $dbh->prepare($sql);
while (<$data_file>) {
my @fields = split "\t";
$sth->execute(@fields);
}
APPROACH_3:
my @inserts;
while (<$data_file>) {
my @fields = split "\t";
my $insert = '('.join(",",@fields).')';
push @inserts, $insert;
if (@inserts == 500) {
my $insert_500 = join ",", @inserts;
$dbh->do("insert into table values $insert_500";
undef @inserts;
}
}
# insert leftovers
【问题讨论】:
-
我对您的结果并不感到惊讶。我没有太多使用 SQLite,但至少对于 MySQL,不仅仅是几行的批量插入比单独插入每一行要快得多。这是有道理的:每次插入都需要与数据库对话,这会产生一定的开销。
-
另外,对于更多的行,使用 DBMS 的本机导入功能导入 CSV 可能更快(对于我的特定应用程序,在插入时,MySQL 的
LOAD DATA INFILE比批量导入要快得多 > ~ 100 行)。 SQLite has a CSV import command,但我不确定你是否可以通过 DBI 使用它。