- vừa được xem lúc

Sử dụng Lazy Collection để export 100,000 bản ghi

0 0 12

Người đăng: Nguyen Quoc Phong

Theo Viblo Asia

Lazy Collection là gì

Lazy Collection được giới thiệu bới Joseph Silber trong Laravel 6.0. Lazy collection là một class cho phép chúng ta duyệt các phần tử trong mảng. Layzy collection sửa dụng PHP generator để cho phép chúng ta làm việc với tập dữ liệu rất lớn và giữ cho mức sử dụng bộ nhớ ở mức thấp.

Bài toán đặt ra

Giá sử rằng CSDL của chúng tao có bảng chứa 100,000 bản ghi và chúng ta muốn lấy tất cả dữ liệu này, có thể xuất ra csv hoặc hiển thị lên cho người dùng

Nếu bạ sử dụng hàm all() trong Laravel Eloquent, hầu hết bộ nhớ của server sẽ được sử dụng để thực hiện truy vấn này. Việc truy vấn này sẽ làm 2 phần : đầu tiên là nạp tất các bản ghi được lấy ra từ CSDL, sau đó lấy đẩy bản ghi này vào collection. Với 100,000 bản ghi việc này sẽ ảnh hưởng đến hệ thống, vì ngoài chức năng này ra hệ thống của chúng ta cũng còn phải thực hiện nhiều chức năng khác (search, insert, update v...v..)

Thật may Laravel 6.0 đã cung cấp cho chúng ta Laravel Collection đễ làm việc với tập dữ liệu lớn với memory sử dụng thấp. Vậy chúng ta cùng bắt đầu nào 😃

Cài đặt môi trường

1. Install composer

php composer-setup.php --install-dir=bin --filename=composer
mv composer.phar /usr/local/bin/composer

2. Install laravel

composer global require laravel/installer

3. Creata new project

laravel new test-lazy-collection

4. Make database

Cài đặt biến DB_DATABASE, DB_USERNAME, DB_PASSWORD trong file .env

5. Tạo seeder data

php artisan make:seeder UsersTableSeeder

Tạo random data

public function run() { DB::table('users')->truncate(); for($i=0; $i<=100; $i++){ factory(App\User::class, 1000)->create(); } }

Update factory data

$factory->define(App\User::class, function (Faker $faker) { return [ 'name' => $faker->name, 'email' => $faker->unique()->safeEmail, 'email_verified_at' => now(), 'password' => bcrypt('123456'), // password 'remember_token' => Str::random(10), ]; });

6. Run seed data

php artisan db:seed

Tạo logic code xử lý export dữ liệu

1. Tạo routes

Route::get('/write', 'UsersController@write'); Route::get('/lazyWrite', 'UsersController@lazyWrite'); 

2. Thêm method checkDirOrMake() trong UserController

private function checkDirOrMake($dirname){ $filename = $dirname . "/"; if (!file_exists($filename)) { mkdir($dirname, 0777); } } 

Hàm checkDirOrMake() sẽ kiểm tra và tạo folder nếu nó có tồn tại hay không

3. write() function để export dữ liệu ra csv

public function write(){ $directory = storage_path("uploads"); $this->checkDirOrMake($directory); $file = fopen($directory."/contacts.csv","w+"); $users = \App\User::all(); foreach($users as $user) { $user = $user->toArray(); fputcsv($file, $user); } fclose($file); } 

4. lazyWrite() để export dữ liệu dùng Lazy Collection

public function lazyWrite(){ $directory = storage_path("uploads"); $this->checkDirOrMake($directory); $file = fopen($directory."/lazy_contacts.csv","w+"); $users = \App\User::cursor() ->each(function ($user) use ($file) { $user = $user->toArray(); fputcsv($file, $user); }); fclose($file); } 

Thay vì sử dụng all() chúng ta sẽ sử dụng method cursor()

5. Run virtual server

php artisan serve

6. Chạy exoprt data

Export bình thường

http://localhost:8000/write

Export sử dụng lazy collection

http://localhost:8000/lazyWrite

7. Kết quả

Khi sử dụng export thông thường memory sẽ tốn rất nhiều trong khi sử dụng http://localhost:8000/lazyWrite việc export 100,000 bản ghi rất dễ dàng và tốn ít memory hơn rất nhiều

Kết luận

Việc sử dụng Lazy Collection sẽ tăng performance cho việc xử lý các tập kết quả lớn, nhưng sẽ là không tối ưu khi làm việc với tập dữ liệu nhỏ. Sử dụng Lazy Collection sẽ tùy vào bài toán cụ thể.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tìm hiểu về Resource Controller trong Laravel

Giới thiệu. Trong laravel, việc sử dụng các route post, get, group để gọi đến 1 action của Controller đã là quá quen đối với các bạn sử dụng framework này.

0 0 335

- vừa được xem lúc

Phân quyền đơn giản với package Laravel permission

Như các bạn đã biết, phân quyền trong một ứng dụng là một phần không thể thiếu trong việc phát triển phần mềm, dù đó là ứng dụng web hay là mobile. Vậy nên, hôm nay mình sẽ giới thiệu một package có thể giúp các bạn phân quyền nhanh và đơn giản trong một website được viết bằng PHP với framework là L

0 0 421

- vừa được xem lúc

Sử dụng Swagger để xây dựng API documentation

Giới thiệu về Swagger. RESTful API là một tiêu chuẩn dùng trong việc thiết kế API cho các ứng dụng web (thiết kế Web services) để tiện cho việc quản lý các resource.

0 0 1k

- vừa được xem lúc

Ví dụ CRUD với Laravel và Vuejs.

1. Cài đặt Laravel. composer create-project --prefer-dist laravel/laravel vuelaravelcrud. .

0 0 141

- vừa được xem lúc

Một số tips khi dùng laravel (Part 1)

1. Show database query in raw SQL format. DB::enableQueryLog(); // Bật tính năng query logging. DB::table('users')->get(); // Chạy truy vấn bạn muốn ghi log.

0 0 69

- vừa được xem lúc

Inertiajs - Xây dựng Single Page App không cần API

Tiêu đề là mình lấy từ trang chủ của https://inertiajs.com/ chứ không phải mình tự nghĩ ra đâu nhé :v. Lâu lâu rồi chưa động tới Laravel (dự án cuối cùng mình code là ở ver 5.8), thế nên một ngày đẹp trời lượn vào đọc docs ver 8.

0 0 227