Мне нужно получить все данные из таблицы mysql. Я пробовал до сих пор:
my $query = $connection->prepare("select * from table");
$query->execute();
while (my @row=$query->fetchrow_array)
{
print format_row(@row);
}
но всегда есть...
Таблица имеет около 600 М строк и, по-видимому, все результаты запроса хранятся в памяти после execute()
. Недостаточно памяти для этого :(
Мой вопрос:
Есть ли способ использовать Perl DBI для получения данных из таблицы по строкам? Что-то вроде этого:
my $query = $connection->prepare("select * from table");
while (my @row=$query->fetchrow_array)
{
#....do stuff
}
btw, разбиение на страницы - замедление:/
очевидно, все результаты запроса хранятся в памяти после выполнения команды execute()
Это поведение по умолчанию для клиентской библиотеки mysql. Вы можете отключить его, используя атрибут mysql_use_result в дескрипторе базы данных или оператора.
Обратите внимание, что блокировка чтения, которую вы будете иметь в таблице, будет удерживаться намного дольше, пока все строки будут переданы в клиентский код. Если это может быть проблемой, вы можете использовать SQL_BUFFER_RESULT.
Метод fetchall_arrayref
принимает два параметра, второй из которых позволяет вам ограничить количество строк, полученных из таблицы одновременно
Следующий код считывает 1000 строк из таблицы за раз и обрабатывает каждый из них
my $sth = $dbh->prepare("SELECT * FROM table");
$sth->execute;
while ( my $chunk = $sth->fetchall_arrayref( undef, 1000 ) ) {
last unless @$chunk; # Empty array returned at end of table
for my $row ( @$chunk ) {
print format_row(@$row);
}
}
При работе с огромными таблицами я создаю пакеты данных с динамически построенными SQL-выражениями, такими как
$sql = "SELECT * FROM table WHERE id>" . $lastid . " ORDER BY id LIMIT " . $packagesize
Приложение будет динамически заполнять $lastid
соответствии с каждым пакетом, который он обрабатывает.
Если в table
есть идентификатор поля id
у нее также есть индекс, построенный на этом поле, чтобы производительность была вполне удовлетворительной.
Он также ограничивает загрузку базы данных небольшими остатками между каждым запросом.
print format_row(@row)