Tìm thấy x bài viết trong xms.

Trên các group trên mạng, mình thấy các bạn hay than thở là có cách nào import nhanh không chứ sao mới có vài nghìn record mà đã mất rất nhiều thời gian rồi!! Nên hôm nay rảnh rổi mình quyết định thử xem là mất bao lâu.

Chuẩn bị

File excel 1 trăm ngàn record (tải về - mình có đính kèm trong source code) nặng 12 MB, có 14 cột

Bắt đầu thôi.

Bước 1: Tạo project laravel mới

composer create-project --prefer-dist laravel/laravel excel-import-100000-record-sample

Bước 2: Tạo database

Tạo database có tên là: excel-import-100000-record sau đó config trong file .env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=excel-import-1million-record
DB_USERNAME=root
DB_PASSWORD=

Bước 3: Tạo bảng imports bằng migration

Mình sẽ tạo 1 bảng có tên là: imports có chưa 14 cột tương ứng với 14 cột trong file excel ở trên kia.

php artisan make:migration create_imports_table --create=imports

File xxxx_xx_xx_xxxxxx_create_imports_table.php sẽ sinh tự động, mình sẽ chỉnh sửa một chút như sau:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateImportsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('imports', function (Blueprint $table) {
            $table->increments('id');
            $table->string('col1');
            $table->string('col2');
            $table->string('col3');
            $table->string('col4');
            $table->string('col5');
            $table->string('col6');
            $table->string('col7');
            $table->string('col8');
            $table->string('col9');
            $table->string('col10');
            $table->string('col11');
            $table->string('col12');
            $table->string('col13');
            $table->string('col14');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('imports');
    }
}

Trong file laravelcms\app\Providers\AppServiceProvider.php function boot() thêm dòng này để chạy migrate khỏi bị lỗi.

public function boot()
{
    \Schema::defaultStringLength(191);
}

Chạy migrate

php artisan migrate

Bước 4: Cài thư viện Excel

Mình sẽ cài thư viện Laravel-Excel bằng cách chạy artisan command

composer require maatwebsite/excel

Bước 5: Đọc file excel và lưu vào database

Vì khi chạy không thông qua giao diện nên mình sẽ tạo 1 command excel:import như sau:

php artisan make:command ImportExcel --command=excel:import

Sau khi file app\Console\Commands\ImportExcel.php được tự động sinh ra, mình sẽ viết logic cho nó như sau

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class ImportExcel extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'excel:import';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        ini_set('memory_limit', '-1');
        set_time_limit(300);

        // Thời gian bắt đầu
        $this->showTime();

        // Đọc file excel
        $inputFileName = public_path($path = '100000 Sales Records.csv');
        $reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
        $reader->setSheetIndex(0);
        $spreadsheet = $reader->load($inputFileName);
        // Load xong file
        $this->showTime();

        // Nạp rows
        $rows = $spreadsheet->getSheet(0)->toArray(null, true, true, true);
        $this->showTime();

        $arrKeys = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7', 'col8', 'col9', 'col10', 'col11', 'col12', 'col13', 'col14'];
        $count = count($rows);

        foreach ($rows as $key => $row) {
            $insert[] = array_combine($arrKeys, $row);

            // Cứ mỗi 1000 rows thì insert db 1 lần
            if ($key%1000 == 999 || $key == $count - 1) {
                \DB::table('imports')->insert($insert);
                $insert = [];
            }
        }

        // Done
        $this->showTime();
    }

    public function showTime()
    {
        $t = microtime(true);
        $micro = sprintf("%06d",($t - floor($t)) * 1000000);
        $d = new \DateTime( date('Y-m-d H:i:s.'.$micro, $t) );
        $this->error('Time: ' . $d->format("Y-m-d H:i:s.u"));
        return $d;
    }
}

Kết quả

Chạy lệnh: php artisan excel:import và cùng xem kết quả nhé

// Thời gian bắt đầu
Time: 2018-08-27 15:04:45.989660
// Load xong file
Time: 2018-08-27 15:05:10.979576
// Nạp rows
Time: 2018-08-27 15:05:28.178913
// Done
Time: 2018-08-27 15:05:37.860093

Đọc xong file 12MB, 100.000 rows, 14 cột mất 25 giây.

Insert 100.000 rows vào DB hết gần 10s

Source code cho anh em nào cần: https://github.com/nguyentranchung/excel-import-100000-record-sample 

Vậy thôi 🥇🥇🥇

Đánh giá bài viết

Thích thì like
Laravel Excel import 100.000 record mất bao lâu?
5/5 2 votes

Bình luận

vu thien avatar
vu thien

Để chạy được Command ở terminal như thế nào vậy bạn

vu thien avatar
vu thien

Mình chạy được rồi 
php artisan excel:import

Chung Nguyễn avatar
Chung Nguyễn

Thanks bạn nhắc nhé! mình viết thiếu khúc đó người mới học sẽ khó hiểu, mình sẽ chỉnh lại sớm

Hiển thị bình luận Facebook