Сохранение памяти при выборке больших наборов результатов с PDO

Я записал инструмент для репликации баз данных в PHP. Это хорошо работает, но существует одна проблема:

Я использую PDO для соединения с различными базами данных для хранения этого независимым от любого определенного RDBMS, который крайне важен для этого приложения.

Инструмент делает некоторый анализ таблиц, чтобы решить, как преобразовать определенные типы и некоторый другой материал. Затем это в значительной степени делает"SELECT * FROM <tablename>"для получения строк, которые должны быть скопированы. Наборы результатов являются довольно большими (о 50k строках в некоторых таблицах).

После этого это выполняет итерации по набору результатов в a while цикл с PDOStatement::fetch();, делает некоторое преобразование типов и выход, сборки INSERT оператор и подача это к целевой базе данных.

Все это работает приятно за одним исключением. При выборке строк, одно ata время, от набора результатов, процесс PHP продолжает съедать все больше памяти. Мой assuption, что PDO сохраняет уже обработанные строки в памяти, пока целый набор результатов не обрабатывается.

Я также abserved, что, когда мой инструмент закончен с одной таблицей и доходами к следующим отбрасываниям потребления памяти немедленно, который поддерживает мою теорию.

Я НЕ сохраняю данные в переменных PHP! Я держу всего одну одну строку в любой данный момент для обработки, таким образом, это не проблема.

Теперь к вопросу: существует ли способ вынудить PDO не сохранить все данные в памяти? Я только обрабатываю одну строку за один раз, таким образом, нет абсолютно никакой потребности сохранить весь тот мусор. Я действительно хотел бы использовать меньше памяти на этой вещи.

1
задан selfawaresoup 2 July 2010 в 11:10
поделиться

1 ответ

Я считаю, что проблема связана со сборщиком мусора php, поскольку он не выполняет сборку мусора достаточно скоро.
Я бы попытался получить свои результаты кусками размером row_count , например «SELCT ... LIMIT offset, row_count» в MySQL или «SELECT * FROM (SELECT. ..) WHERE ROW_NUM BETWEEN offset AND (offset + row_count) " в ORACLE.
Используя Zend_Db_Select , можно генерировать запросы, не зависящие от БД:

$select = $db->select()
    ->from(array('t' => 'table_name'),
        array('column_1', 'column_2'))
    ->limit($row_count, $offset);
$select->__toString(); 
# on MySQL renders: SELECT column_1, column_2 FROM table_name AS t LIMIT 10, 20
2
ответ дан 2 September 2019 в 23:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: