Jako programiści, nasze wybory mogą mieć duży wpływ na wydajność i wykorzystanie pamięci przez nasze aplikacje. Laravel oferuje nam różne metody pobierania danych z baz danych, takie jak pobiera wszystkie rekordy
, chunk()
, i lazy()
. Ten artykuł ma na celu zbadanie tych metod, podkreślając ich unikalne cechy. Porównamy je za pomocą nieformalnych testów porównawczych, aby zrozumieć ich wpływ na zużycie pamięci i szybkość. Należy zauważyć, że te punkty odniesienia nie mają charakteru naukowego, ale powinny zapewnić użyteczny obraz porównawczy.
Szybkie podsumowanie
Method | Description | Eager Load | Low Memory | Concurrent Safe |
---|---|---|---|---|
pobiera wszystkie rekordy |
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 |
Testy porównawcze
Należy pamiętać, że testy porównawcze użyte w tym artykule nie są naukowe i zostały przeprowadzone na systemie Laravel 8.74 i PHP 7.4.25 w systemie macOS z Laravel Valet. Wszystkie testy przeprowadzono z Laravel 8.74 i PHP 7.4.25 na macOS z Laravel Valet.
10 000 rekordów 100 000 rekordów
Method | Memory | Time |
---|---|---|
pobiera wszystkie rekordy |
26 MB | 261ms |
cursor() |
12 MB | 460ms |
lazy() |
9MB | 300ms |
chunk() by 500 |
6MB | 400ms |
Metody
Method | Memory | Time |
---|---|---|
pobiera wszystkie rekordy |
277 MB | 2.72sec |
cursor() |
75 MB | 5.8sec |
lazy() |
9MB | 5.4sec |
chunk() by 500 |
6MB | 7.56sec |
pobiera wszystkie rekordyMetoda pobiera wszystkie rekordy
wykorzystująca funkcję fetchAll()
pobiera wszystkie rekordy
The pobiera wszystkie rekordy
method, employing the fetchAll() function, fetches all database records in a single operation. This method offers the highest speed among the alternatives; however, it comes at the cost of significant memory consumption. Thus, it’s best-suited for scenarios where you’re working with smaller datasets and where ample memory resources are available.
- Oferuje najszybszy dostęp do danych
- Zużywa dużo pamięci
chunk()
The chunk()
method uses fetchAll() to retrieve data, similar to the pobiera wszystkie rekordy
method. However, instead of retrieving all records at once, it breaks the process down into smaller, manageable “chunks”. This approach dramatically reduces memory consumption, especially for larger datasets, by limiting the number of records retrieved at once based on a specified chunk size.
Despite being slower than pobiera wszystkie rekordy
, chunk()
shines in scenarios where memory conservation is paramount. When performing operations that involve iterating and updating records simultaneously, consider using chunkById()
to avoid potential issues, particularly when dealing with changes to primary or foreign keys.
- Best for memory conservation, especially with larger datasets
- Less speedy in comparison to
pobiera wszystkie rekordy
- Potential complications in concurrency. If you are updating the same records you are iterating over (within the chunk operation), you may run into issues.
cursor()
The cursor()
method leverages PHP´s fetch()
function to retrieve records from the database buffer one at a time. As a result, it uses less memory than pobiera wszystkie rekordy
, making it more efficient for handling larger datasets. However, the trade-off is speed; it’s slower due to its one-by-one record iteration. An important advantage of cursor()
is its consistency in processing datasets that might be subject to change during the processing period.
- Effective memory usage - ideal for large datasets
- Consistently processes datasets even when data changes during the operation
- Slower than
pobiera wszystkie rekordy
- Unable to handle eager loading of relationships
- There’s a potential for memory exhaustion depending on the buffer size, particularly with extremely large collections
lazy()
Wprowadzony w Laravel 8, metoda lazy()
jest bardziej przyjazną składniowo wersją chunk()
. Podobnie jak chunk()
, lazy()
pobiera rekordy w małych segmentach. Jednak zamiast wymagać wywołania zwrotnego, lazy()
wykorzystuje generatory PHP. Powoduje to uproszczoną składnię, ponieważ zwraca LazyCollection dla Twojej wygody.
Metoda lazy() zapewnia równowagę między efektywnym wykorzystaniem pamięci a czytelnością. Podczas obsługi większych zestawów danych i wykonywania operacji obejmujących jednoczesne iterowanie i aktualizowanie rekordów można zachować lazyById()
spójność danych, szczególnie podczas aktualizowania kluczy podstawowych lub obcych.
- Efficient memory usage similar to
chunk()
- Provides a cleaner syntax due to PHP generators
- Slower than
pobiera wszystkie rekordy
- Unable to handle eager loading of relationships
- Possible concurrency Issues: If the underlying data changes during the iteration process, there might be inconsistencies in the results.
- Suited for operations that require simultaneous iteration and updates on records, using
lazyById()
Wniosek
As we’ve explored, Laravel offers a variety of methods for data retrieval, each with its own unique strengths and weaknesses. The pobiera wszystkie rekordy
and chunk()
methods, perhaps the most commonly used, offer distinct benefits. pobiera wszystkie rekordy
, while fast and capable of eager loading, consumes substantial memory, which may limit its utility with large datasets. On the other hand, chunk()
method allows for memory efficiency with larger datasets and supports eager loading, but isn’t safe for operations where data changes concurrently.
Rzadziej stosowana, ale nadal wydajna, metoda wyróżnia się wydajnością pamięci i równoczesnym bezpieczeństwem, cursor()
mimo że jest wolniejsza i nie obsługuje chętnego ładowania. Wreszcie, nowicjusz w ekosystemie Laravel, zapewnia równowagę wydajności pamięci i prostszej chunk()
składni, ale, podobnie jak cursor()
, lazy()
nie obsługuje chętnego ładowania i nie jest bezpieczny przy jednoczesnej zmianie danych.
Ostatecznie wybór metody powinien być podyktowany konkretnymi potrzebami aplikacji:
- Rozmiar danych
- Dostępna pamięć systemowa
- Wymóg dla chętnego załadunku
- Czy dane mogą ulec zmianie podczas operacji.
While pobiera wszystkie rekordy
and chunk()
are popular for a reason, every method has its place, and the optimal choice always depends on the context. Equipped with an understanding of each method’s trade-offs, you’re now prepared to make an informed decision that best optimizes your application’s performance and memory usage.