Robert & Laravel
Я тут думал, как уменьшить количество запросов в Laravel при загрузке сложного набора связанных моделей. Ты пробовал eager loading с ограничениями или, может быть, новые Lazy Collections? Как считаешь, какие компромиссы тут?
Привет, ну обычно, если данные нужны сразу, лучше использовать eager loading с ограничениями – один запрос к базе и сразу всё, но с условиями в запросе нужно аккуратно, чтобы не вытащить лишнего. Lazy Collections позволяют стримить результаты и работать с ними в памяти, чтобы избежать загрузки огромных коллекций, но ты всё равно платишь за запрос на каждый фрагмент и теряешь возможность использовать связи как с eager loading. Короче говоря, если нужна скорость и памяти хватает – eager с ограничениями чище; если экономишь память и готов немного подождать – lazy collections могут оказаться лучшим вариантом.
Звучит логично. Если хватит памяти, просто `with(['relation'=>function($q){…}])` и всё готово. Для действительно огромных объёмов данных переходи на `chunk` или `LazyCollection` – это платит за запрос по частям, но память под контролем. Главное – держать ограничение жёстким; иначе просто заменишь одну узкую горлышку на другую.
Отличные соображения – действительно, жёсткие ограничения сокращают избыточные строки. Если столкнёшься с нехваткой памяти, этот приём с разбиением на чанки иногда спасает ситуацию, только не забудь индексировать столбцы, по которым фильтруешь. Это компромисс, но пара грамотно поставленных условий обычно справляется с основной работой.
Именно – индекс – настоящий незаметный герой при работе с чанкингом. Забудешь его – база данных все равно будет сканировать всю таблицу для каждого чанка, так что просто меняешь один медленный шаг на другой. Правильно подобранное условие `WHERE`, подкрепленное индексом, может сократить время сканирования с линейного до логарифмического, и это огромная разница, когда речь идет о миллионах строк. Так что сначала индексируй, потом уже занимайся чанкингом.
Понял – сначала метки, потом детали, вот девиз.