我正在尝试使用sql检索一堆行(作为测试 - 假设每次迭代中有1000行,最多可达100万行)并存储在一个文件中(在我的情况下为.store文件,但可能是文本文件 - 没关系)批量避免内存不足问题。我是perl脚本中的sql。
如果有人可以分享一个例子,我们将不胜感激。
示例就像 -
sub query{
$test = "select * from employees";
return $test;
}
// later in the code -
my $temp;
my $dataset=DBUtils::make_database_iterator({query=> test($temp)});
}
store $dataset, $result_file;
return;
答案 0 :(得分:2)
我能为您提供的最佳信息是,它使用SELECT
语句的LIMIT
子句从表中检索有限数量的行。
显然,您必须自己提供DSN的实际值,表的名称以及store_block
子例程。
use strict;
use warnings;
use autodie;
use DBI;
my $blocksize = 1000;
my ($dsn, $user, $pass) = (...);
my $dbh = DBI->connect($dsn, $user, $pass);
my $sth = $dbh->prepare('SELECT * FROM table LIMIT ? OFFSET ?') or die $DBI::errstr;
open my $fh, '>', 'test.store';
for (my $n = 0; $sth->execute($blocksize, $n * $blocksize); ++$n) {
my $block = $sth->fetchall_arrayref;
last unless @$block;
store_block($block, $fh);
}
close $fh;
sub store_block {
my ($block, $fh) = @_;
...
}
答案 1 :(得分:0)
您说您希望批量工作以避免内存不足错误。这表明你正在做这样的事情......
my @all_the_rows = query_the_database($sql);
store_stuff(@all_the_rows);
您希望尽可能避免这样做,因为如果数据集变大,您可能会耗尽内存。
相反,您可以一次读取一行,并使用DBI一次写一行。
use strict;
use warnings;
use DBI;
# The file you're writing results to
my $file = '...';
# Connect to the database using DBI
my $dbh = DBI->connect(
...however you do that...,
{RaiseError => 1} # Turn on exceptions
);
# Prepare and execute the statement
my $sth = $dbh->prepare("SELECT * FROM employees");
$sth->execute;
# Get a row, write a row.
while( my $row = $sth->fetchrow_arrayref ) {
append_row_to_storage($row, $file);
}
我留下append_row_to_storage
写给你。