Эти последние 3 байта были соломой, которая сломала спину верблюду. Вероятно, попытка выделения в длинной строке выделений приводит к ошибке.
К сожалению libpq
будет пытаться полностью кэшировать результирующие наборы в памяти , прежде чем передать управление приложению. Это в дополнение к памяти, которую вы используете в $myArray
.
Было предложено использовать LIMIT ... OFFSET ...
для уменьшения огибающей памяти; это будет работать, но неэффективно , поскольку может без необходимости дублировать усилия по сортировке на стороне сервера каждый раз, когда запрос переиздается с другим смещением (например, для ответа на LIMIT 10 OFFSET 10000
, Postgres все равно придется сортировать весь набор результатов, только чтобы вернуть строки 10000..10010.)
Вместо этого используйте DECLARE ... CURSOR
для создания серверного курсора , а затем FETCH FORWARD x
для извлечения следующих x
строк. Повторите столько раз, сколько необходимо или до тех пор, пока не будут возвращены строки меньше чем x
. Не забудьте CLOSE
курсор, когда вы закончите, даже когда / если исключение поднято.
Также не SELECT *
; если вам нужны только id
и name
, создайте курсор FOR SELECT id, name
(иначе libpq
будет без необходимости извлекать и кэшировать столбцы, которые вы никогда не используете, увеличивая объем памяти и общее время запроса.)
Используя курсоры, как показано выше, libpq
будет одновременно хранить не более x
строк в памяти. Тем не менее, убедитесь, что вы также очищаете $myArray
между FETCH
es, если это возможно, иначе у вас все еще может быть недостаточно памяти из-за $myArray
.