【问题标题】:DBD::SQLite fastest way to insert multiple rowsDBD::SQLite 插入多行的最快方法
【发布时间】: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 使用它。

标签: perl sqlite dbi


【解决方案1】:

请参阅下面的示例,其中自动提交设置为 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 个插入或任何您认为最好的。如果不提交,如果出现错误或计算机关闭,那么您将只创建上次提交时的记录数 - 这是一个困难的情况。

【讨论】:

  • 没有考虑过自动提交。明天试试,谢谢。
  • 我终于开始测试这个了。你是对的。禁用自动提交真的非常快。谢谢。
  • @beasy 很高兴能帮上忙。很高兴解决了您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-07
  • 2012-01-31
  • 2013-04-11
相关资源
最近更新 更多