Не знаю. В некоторых фреймворках есть подход с batch - указать, сколько дергать элементов за 1 раз. Например, вытаскивать по 100 клиентов. Тогда можно соблюсти баланс расхода памяти и обращений к БД.
Нет, например при использовании PostgresQL, делается один запрос, как обычно, только возвращается не весь результат, а итератор, который построчно этот результат, по мере итерирования из постгреса забирает.
@@SergeyFedosovfso Вы имеете в виду ORM Doctrine + PostgresQL? К СУБД можно через DAO, AR, ORM обращаться. Сама Доктрина умеет с любой СУБД $qb->getQuery()->toIterable().
Нет. Наоборот, запрос будет только один. К примеру, в базе есть 1000 записей и надо по ним по всем пройтись. Вариант 1. Table::all() = 1 запрос к базе = получаем коллекцию с 1000 объектов моделей в памяти Вариант 2. Table::query()->lazy(200) = 5 запросов = коллекция из 200 объектов в памяти Вариант 3. Table::query()->cursor() = 1 запрос = lazy-коллекция с 1 объектом в памяти При работе через курсор из базы одним запросом вытаскиваются все данные, но не создаются объекты моделей. Сама модель создаётся только в момент, когда она запрашивается при проходе через коллекцию. С курсорами есть пара минусов: 1. нет возможности подтянуть одним запросом все связи для моделей. И вот тут уже будет куча запросов к базе, если будут обращения к связям. 2. если надо обработать очень много записей из базы. Т.к. одним запросом вытаскиваются все данные, то они так же могут не уместиться в памяти. Получается, что вариант 2 (chunk или lazy) - золотая середина. И связи подтянуть можно и памяти можно сэкономить по сравнению с первым вариантом. А так всё очень зависит от конкретной ситуации.
по идее после цикла while нужно добавить fclose($handle);
А если нужно например вернуть модель виз рилейшн? Вроде бы курсор так не может, так какой вариант решает такой кейс?
👍
🌟
Ах автор как же ты молотишь функциями и замыканиями! Обалдеть. Как заведенный.
тренировки
Слово yield правильно произноситься как "йелд"
Я же правильно понял, что в данном примере мы экономим память, но генерируем тысячи запросов, чтобы обойти коллекцию?
Не знаю. В некоторых фреймворках есть подход с batch - указать, сколько дергать элементов за 1 раз. Например, вытаскивать по 100 клиентов. Тогда можно соблюсти баланс расхода памяти и обращений к БД.
Нет, например при использовании PostgresQL, делается один запрос, как обычно, только возвращается не весь результат, а итератор, который построчно этот результат, по мере итерирования из постгреса забирает.
Интересный ты вопрос написал, тоже стало любопытно, как это конкретно работает
@@SergeyFedosovfso Вы имеете в виду ORM Doctrine + PostgresQL? К СУБД можно через DAO, AR, ORM обращаться. Сама Доктрина умеет с любой СУБД $qb->getQuery()->toIterable().
Нет. Наоборот, запрос будет только один.
К примеру, в базе есть 1000 записей и надо по ним по всем пройтись.
Вариант 1. Table::all() = 1 запрос к базе = получаем коллекцию с 1000 объектов моделей в памяти
Вариант 2. Table::query()->lazy(200) = 5 запросов = коллекция из 200 объектов в памяти
Вариант 3. Table::query()->cursor() = 1 запрос = lazy-коллекция с 1 объектом в памяти
При работе через курсор из базы одним запросом вытаскиваются все данные, но не создаются объекты моделей. Сама модель создаётся только в момент, когда она запрашивается при проходе через коллекцию.
С курсорами есть пара минусов:
1. нет возможности подтянуть одним запросом все связи для моделей. И вот тут уже будет куча запросов к базе, если будут обращения к связям.
2. если надо обработать очень много записей из базы. Т.к. одним запросом вытаскиваются все данные, то они так же могут не уместиться в памяти.
Получается, что вариант 2 (chunk или lazy) - золотая середина. И связи подтянуть можно и памяти можно сэкономить по сравнению с первым вариантом. А так всё очень зависит от конкретной ситуации.