web-dev-qa-db-ja.com

Laravelの非常に大きなデータのインポートプロセスを最適化する方法

約500万の非常に大量のレコードをインポートする機能があります。

インポートプロセスでも、関連するテーブルのエントリを同時に作成する必要があります。

新しいエントリの束挿入クエリを作成し、すべてのクエリを処理して、チャンクでプロセスを作成する必要があります。

プロセスをスピードアップする他の方法は何ですか?

8
Vivek Solanki

(ララキャストからコピー)これもおそらく役立つでしょう:

DB::connection()->disableQueryLog();

「デフォルトでは、Laravelは、現在のリクエストに対して実行されたすべてのクエリのログをメモリに保持します。ただし、多数の行を挿入する場合など、これにより、過剰なメモリを使用するアプリケーション。」

3
manu

したがって、すべてのコメントを個別に確認する必要がない人のために要約します。

  • Eloquentモデルの代わりに、DBファサードLaravelオファーを パフォーマンスの向上 の使用に使用します。
  • すべてのデータを一度にインポートするのではなく、インポートプロセスをバッチで実行します。
  • クエリロギングを無効にする メモリ使用量を節約します。
  • インポートは、Webリクエスト中ではなく、バックグラウンドジョブで実行します。

すでに指摘した点に加えて、次のことを検討できます。

  • 最初に、入力のxlsx/csvファイルを50行(またはその他の適切な数)のバッチで読み取るジョブを実行します。すべての行をメモリに保持しないようにしてください。次に、行のバッチごとに新しいジョブを作成します。したがって、2ステップのインポートができます。
  • バッチごとに個別のジョブを作成する場合、それらのジョブを同時に実行できます(=同時に複数のキューワーカー)。
  • インポートが完了するのを待っているユーザーがいる場合は、プログレスバーまたは少なくとも何らかのアニメーションローダーを表示していることを確認してください。これはプロセスをスピードアップしませんが、彼らは仕事が行われていることを示します。
  • データベーストランザクション を活用して、一度に複数のデータベースクエリを実行することもできます(このクレジットは Philippe Thiers のクレジットです)
1
PtrTon

使用する:

チャンクでデータを処理するLaravelキューを使用する

使用 https://docs.laravel-Excel.com/3.1/imports/ ユーザーモデルバインディングの例

namespace App\Imports;

use App\User;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\Importable;

class UsersImport implements ToModel
{
    use Importable;

  public function model(array $row)
  {
      return new User([
       'name'     => $row[0],
       'email'    => $row[1],
       'password' => Hash::make($row[2]),
    ]);
  }
}

コントローラ内

(new UsersImport)->import('users.xlsx', 'local', \Maatwebsite\Excel\Excel::XLSX);
0
bhavinG