DBD::SQLite 插入多行的最快方法

DBD::SQLite fastest way to insert multiple rows

我尝试了 3 种不同的方法来将多行(超过 500 行)插入 SQLite table。与直觉相反,下面的方法 3 是最快的。我原以为方法 2 是最快的,因为它使用 "prepared" 语句句柄。但是我的第三种方法——一次插入 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

请参阅下面的示例,其中自动提交设置为 0

#!/usr/bin/perl
use strict;
use warnings;
use DBI;

my $dbh = DBI->connect("dbi:SQLite:dbname=pedro.lite","","",
    {PrintError => 1, AutoCommit => 0}) or die "Can't connect";

my $sth = $dbh->prepare(q{INSERT INTO purchases VALUES(?,?,?,?)})
    or die $dbh->errstr;

while (<DATA>) {
    chomp;
    $sth->execute( split /\|/ );
}

$dbh->commit() or die $dbh->errstr;

__DATA__
Pedro|groceries|apple|1.42 
Nitin|tobacco|cigarettes|15.00 
Susie|groceries|cereal|5.50 
Susie|groceries|milk|4.75 
Susie|tobacco|cigarettes|15.00 
Susie|fuel|gasoline|44.90 
Pedro|fuel|propane|9.60 

这将禁用提交,直到插入所有记录。实际上,如果有很多插入,您可能不想等待提交 - 可能每 5000 次插入或您认为最好的任何时间。通过不提交,如果出现错误或计算机关闭,那么您将只会创建上次提交时的记录数 - 一个困难的情况。