Как пройти большой набор результатов с помощью perl и postgresql - PullRequest
0 голосов
/ 17 декабря 2018

Привязки DBD::Pg PostgreSQL для Perl всегда будут извлекать весь набор результатов вашего запроса.Таким образом, если вы используете простое подготовительное выполнение для обхода большой таблицы, вы получите всю таблицу в памяти, просто запустив $sth->execute().Подготовленные операторы и вызовы типа fetch_row не помогают.

При работе с БОЛЬШОЙ таблицей произойдет сбой следующего.

use DBI;
my $dbh =   DBI->connect("dbi:Pg:dbname=big_db","user","password",{
        AutoCommit => 0,
        ReadOnly => 1,
        PrintError => 1,
        RaiseError =>  1,
});

my $sth = $dbh->prepare('SELECT * FROM big_table');
$sth->execute(); #prepare to run out of memory here
while (my $row = $sth->fetchrow_hashref('NAME_lc')){
  # do something with the $row hash
}
$dbh->disconnect();

1 Ответ

0 голосов
/ 17 декабря 2018

Чтобы обойти эту проблему, объявите курсор.А затем получить блоки данных с помощью курсора.Настройки ReadOnly и AutoCommit важны для этого.Так как PostgreSQL будет делать CURSORS только для чтения.

use DBI;
my $dbh =   DBI->connect("dbi:Pg:dbname=big_db","user","password",{
        AutoCommit => 0,
        ReadOnly => 1,
        PrintError => 1,
        RaiseError =>  1,
});

$dbh->do(<<'SQL');
DECLARE mycursor CURSOR FOR
SELECT * FROM big_table
SQL

my $sth = $dbh->prepare("FETCH 1000 FROM mycursor");
while (1) {
  warn "* fetching 1000 rows\n";
  $sth->execute();
  last if $sth->rows == 0;
  while (my $row = $sth->fetchrow_hashref('NAME_lc')){
    # do something with the $row hash
  }
}
$dbh->disconnect();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...