• Время чтения ~4 мин
  • 10.10.2023

Наш выбор как разработчиков может сильно повлиять на производительность и использование памяти нашими приложениями. Laravel предлагает нам различные методы извлечения данных из баз данных, таких как get(), chunk(), и lazy(). В данной статье мы рассмотрим эти методы, выделив их уникальные характеристики. Мы сравним их с помощью некоторых неформальных тестов, чтобы понять их влияние на использование памяти и скорость. Обратите внимание, что эти критерии не являются научными, но должны обеспечить полезную сравнительную картину.

Краткий обзор

Method Description Eager Load Low Memory Concurrent Safe
get() Fetches all records at once, fastest method. Yes No Yes
chunk() Retrieves data in small “chunks,” conserving memory. Yes Yes No
cursor() Retrieves data one record at a time, saving memory. No Yes Yes
lazy() Fetches records in small segments using PHP generators, simplifying the syntax. No Yes No

тестов Обратите

внимание, что тесты, используемые в этой статье, не являются научными и проводились в системе под управлением Laravel 8.74 и PHP 7.4.25 на macOS с Laravel Valet. Все тесты проводились с Laravel 8.74 и PHP 7.4.25 на macOS с Laravel Valet.

10 000 записей 100 000 записей

Method Memory Time
get() 26 MB 261ms
cursor() 12 MB 460ms
lazy() 9MB 300ms
chunk() by 500 6MB 400ms

Method Memory Time
get() 277 MB 2.72sec
cursor() 75 MB 5.8sec
lazy() 9MB 5.4sec
chunk() by 500 6MB 7.56sec

Методы

get()

Метод, get() использующий функцию fetchAll(), извлекает все записи базы данных за одну операцию. Этот метод предлагает самую высокую скорость среди альтернатив; Однако это достигается за счет значительного потребления памяти. Таким образом, он лучше всего подходит для сценариев, в которых вы работаете с небольшими наборами данных и где доступно достаточно ресурсов памяти.

  • Обеспечивает максимально быстрое извлечение данных
  • Потребляет большой объем памяти

chunk()

Метод chunk() использует fetchAll() для получения данных, аналогично методу get() . Однако вместо того, чтобы извлекать все записи сразу, он разбивает процесс на более мелкие, управляемые «части». Такой подход значительно снижает потребление памяти, особенно для больших наборов данных, ограничивая количество записей, извлекаемых за один раз, в зависимости от заданного размера блока.

Несмотря на то, что он медленнее, чем get(), он отлично подходит для сценариев, chunk() где сохранение памяти имеет первостепенное значение. При выполнении операций, включающих одновременную итерацию и обновление записей, рассмотрите возможность их использования chunkById() , чтобы избежать потенциальных проблем, особенно при работе с изменениями первичных или внешних ключей.

  • Лучше всего подходит для сохранения памяти, особенно при работе с большими наборами данных
  • Менее быстрый по сравнению с get()
  • Возможные сложности при параллелизме. Если вы обновляете те же записи, которые вы перебираете (в рамках операции блока), вы можете столкнуться с проблемами.

cursor()

использует cursor() функцию PHP fetch() для извлечения записей из буфера базы данных по одной. В результате он использует меньше памяти, чем get(), что делает его более эффективным для обработки больших наборов данных. Тем не менее, компромиссом является скорость; Он медленнее из-за одной итерации записи. Важным преимуществом cursor() является согласованность в обработке наборов данных, которые могут быть изменены в течение периода обработки.

  • Эффективное использование памяти — идеально подходит для больших наборов данных
  • Согласованная обработка наборов данных даже при изменении данных во время операции
  • Медленнее, чем get()
  • Не справляется с интенсивной загрузкой связей
  • Существует вероятность исчерпания памяти в зависимости от размера буфера, особенно при очень больших коллекциях

lazy()

Представленный в Laravel 8, lazy() метод представляет собой более дружественную к синтаксису версию chunk(). Как chunk()и , lazy() извлекает записи небольшими сегментами. Однако вместо того, чтобы требовать обратного вызова, lazy() использует генераторы PHP. Это приводит к упрощенному синтаксису, так как для вашего удобства он возвращает LazyCollection.

Метод lazy() обеспечивает баланс между эффективным использованием памяти и удобочитаемостью. При работе с большими наборами данных и выполнении операций, включающих одновременную итерацию и обновление записей, можно использовать lazyById() для поддержания согласованности данных, особенно при обновлении первичных или внешних ключей.

  • Эффективное использование памяти, аналогичное chunk()
  • Обеспечивает более чистый синтаксис благодаря генераторам PHP
  • Медленнее, чем get()
  • Не справляется с интенсивной загрузкой связей
  • Возможные проблемы с параллелизмом: Если базовые данные изменяются в процессе итерации, в результатах могут быть несоответствия.
  • Подходит для операций, требующих одновременной итерации и обновления записей, используя lazyById()

Заключение

Как мы уже выяснили, Laravel предлагает множество методов получения данных, каждый из которых имеет свои уникальные сильные и слабые стороны. Методы get() and chunk() , возможно, наиболее часто используемые, предлагают явные преимущества. , несмотря на то, что они быстры и способны к быстрой загрузке, потребляют значительный объем памяти, что может ограничить их полезность при работе с большими наборами данных. get() С другой стороны, метод позволяет эффективно использовать память при работе с большими наборами данных и поддерживает ускоренную загрузку, но небезопасен для операций, chunk() в которых данные изменяются одновременно.

Менее часто используемый, но по-прежнему мощный, этот метод выделяется своей эффективностью использования памяти и безопасностью параллельных операций, несмотря на то, cursor() что он медленнее и не поддерживает быструю загрузку. Наконец, lazy()новичок в экосистеме Laravel обеспечивает баланс chunk()эффективности использования памяти и более простого синтаксиса, но, как cursor()и , не поддерживает нетерпеливую загрузку и не безопасен при одновременном изменении данных.

В конечном счете, выбор метода должен основываться на конкретных потребностях вашего приложения:

  • Размер ваших данных
  • Доступная системная память
  • Требование к быстрой загрузке
  • Могут ли данные измениться во время операции.

chunk() Несмотря на то, что get() они популярны не просто так, каждый метод имеет свое место, и оптимальный выбор всегда зависит от контекста. Вооружившись пониманием компромиссов каждого метода, вы готовы принять обоснованное решение, которое наилучшим образом оптимизирует производительность и использование памяти вашего приложения.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Об авторе CrazyBoy49z
WORK EXPERIENCE
Контакты
Ukraine, Lutsk
+380979856297