Как получить данные из большой таблицы строка за строкой

0

Мне нужно получить все данные из таблицы 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, разбиение на страницы - замедление:/

Показать ещё 1 комментарий
Теги:
dbi

3 ответа

2
Лучший ответ

очевидно, все результаты запроса хранятся в памяти после выполнения команды execute()

Это поведение по умолчанию для клиентской библиотеки mysql. Вы можете отключить его, используя атрибут mysql_use_result в дескрипторе базы данных или оператора.

Обратите внимание, что блокировка чтения, которую вы будете иметь в таблице, будет удерживаться намного дольше, пока все строки будут переданы в клиентский код. Если это может быть проблемой, вы можете использовать SQL_BUFFER_RESULT.

  • 0
    Большой! Спасибо. Это именно то, что я ищу;)
2

Метод 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);
    }
}
  • 0
    К сожалению, это решение не решает проблему с памятью. Все данные хранятся в памяти после выполнения ... Это не то, что я ищу, но все равно спасибо.
0

При работе с огромными таблицами я создаю пакеты данных с динамически построенными SQL-выражениями, такими как

$sql = "SELECT * FROM table WHERE id>" . $lastid . " ORDER BY id LIMIT " . $packagesize

Приложение будет динамически заполнять $lastid соответствии с каждым пакетом, который он обрабатывает.

Если в table есть идентификатор поля id у нее также есть индекс, построенный на этом поле, чтобы производительность была вполне удовлетворительной.
Он также ограничивает загрузку базы данных небольшими остатками между каждым запросом.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню