LazyCollections и PHP генераторы. Как применять на практике

Поделиться
HTML-код
  • Опубликовано: 1 дек 2024

Комментарии • 18

  • @voxtens
    @voxtens Год назад +7

    по идее после цикла while нужно добавить fclose($handle);

  • @irivka8344
    @irivka8344 11 месяцев назад

    А если нужно например вернуть модель виз рилейшн? Вроде бы курсор так не может, так какой вариант решает такой кейс?

  • @rustamergashev7278
    @rustamergashev7278 Год назад

    👍

  • @eb6006
    @eb6006 Год назад +1

    Ах автор как же ты молотишь функциями и замыканиями! Обалдеть. Как заведенный.

  • @ЯковЛазоренко
    @ЯковЛазоренко 11 месяцев назад +2

    Слово yield правильно произноситься как "йелд"

  • @sufir
    @sufir Год назад +3

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

    • @borisn879
      @borisn879 Год назад

      Не знаю. В некоторых фреймворках есть подход с batch - указать, сколько дергать элементов за 1 раз. Например, вытаскивать по 100 клиентов. Тогда можно соблюсти баланс расхода памяти и обращений к БД.

    • @SergeyFedosovfso
      @SergeyFedosovfso Год назад +2

      Нет, например при использовании PostgresQL, делается один запрос, как обычно, только возвращается не весь результат, а итератор, который построчно этот результат, по мере итерирования из постгреса забирает.

    • @eb6006
      @eb6006 Год назад

      Интересный ты вопрос написал, тоже стало любопытно, как это конкретно работает

    • @borisn879
      @borisn879 Год назад

      @@SergeyFedosovfso Вы имеете в виду ORM Doctrine + PostgresQL? К СУБД можно через DAO, AR, ORM обращаться. Сама Доктрина умеет с любой СУБД $qb->getQuery()->toIterable().

    • @pnoper
      @pnoper Год назад +12

      Нет. Наоборот, запрос будет только один.
      К примеру, в базе есть 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) - золотая середина. И связи подтянуть можно и памяти можно сэкономить по сравнению с первым вариантом. А так всё очень зависит от конкретной ситуации.