Laravel-datatables: μ„œλ²„ μΈ‘ 내보내기 200000 λ ˆμ½”λ“œ

에 λ§Œλ“  2018λ…„ 03μ›” 31일  Β·  19μ½”λ©˜νŠΈ  Β·  좜처: yajra/laravel-datatables

문제 μš”μ•½ λ˜λŠ” κΈ°λŠ₯ μš”μ²­

200000이 데이터λ₯Ό λ‚΄λ³΄λ‚΄λŠ” 방법을 기둝 ν•  λ•Œ. "ν—ˆμš© 된 λ©”λͺ¨λ¦¬ 크기가 134217728 λ°”μ΄νŠΈ μ†Œμ§„ 됨" 데이터λ₯Ό 내보낼 λ•Œμ΄ μ˜ˆμ™Έκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.

yajra / datatable에 λ§Žμ€ μ–‘μ˜ 데이터λ₯Ό λ‚΄λ³΄λ‚΄λŠ” λ‹€λ₯Έ μ˜΅μ…˜μ€ λ¬΄μ—‡μž…λ‹ˆκΉŒ?

λ§Žμ€ μ–‘μ˜ 데이터λ₯Ό λ‚΄λ³΄λ‚΄λŠ” λ‹€λ₯Έ 방법을 μ œκ³΅ν•˜μ‹­μ‹œμ˜€.

μ„œλ²„μ— μ œν•œλœ μ–‘μ˜ 램이 μžˆμŠ΅λ‹ˆλ‹€.

문제의 μ½”λ“œ 슀 λ‹ˆνŽ«

public function showData(ServiceDataTable $dataTable)
    {
        return $dataTable
            ->render('dataTable.renderDataTable');
    }

μ‹œμŠ€ν…œ μ„ΈλΆ€ 정보

  • 운영 체제 : Ubuntu 16.04
  • PHP 버전 : 7.0.0
  • Laravel 버전 : 5.5
  • Laravel-Datatables 버전 : 8.0
  • Laravel-Datatables λ²„νŠΌ 버전 : 3.1
performance question

λͺ¨λ“  19 λŒ“κΈ€

이 λŒ€λŸ‰ μš”μ²­μ„ μ²˜λ¦¬ν•˜λ €λ©΄ 고유 ν•œ Excel 파일 μž‘μ„±κΈ°λ₯Ό κ΅¬ν˜„ν•΄μ•Όν•©λ‹ˆλ‹€. ServiceDataTable ν΄λž˜μŠ€μ—μ„œ protected function buildExcelFile() λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ν•˜κ³  청크 등을 μˆ˜ν–‰ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ laravel-excel λ¬Έμ„œλ₯Ό μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€.

    /**
     * Build excel file and prepare for export.
     *
     * <strong i="7">@return</strong> \Maatwebsite\Excel\Writers\LaravelExcelWriter
     */
    protected function buildExcelFile()
    {
        /** <strong i="8">@var</strong> \Maatwebsite\Excel\Excel $excel */
        $excel = app('excel');

        return $excel->create($this->getFilename(), function (LaravelExcelWriter $excel) {
            $excel->sheet('exported-data', function (LaravelExcelWorksheet $sheet) {
                $sheet->fromArray($this->getDataForExport());
            });
        });
    }

λ‹€μŒ μ½”λ“œ 생성 μ˜ˆμ™Έ
$this->getDataForExport();
μ„œλ²„ μΈ‘ editColumn() μ •μ˜ λ˜λŠ” μ‚¬μš©μ‹œ μ˜ˆμ™Έλ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€.
200000 개의 λ ˆμ½”λ“œκ°€ μžˆμŠ΅λ‹ˆλ‹€.
μ²˜λ¦¬ν•˜μ§€ μ•Šκ±°λ‚˜ 더 λ§Žμ€ λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•˜μ§€ μ•Šκ³  데이터λ₯Ό κ°€μ Έ μ˜€λŠ” λ‹€λ₯Έ 방법이 μžˆμŠ΅λ‹ˆκΉŒ?
λ‹€μŒ 링크가 μžˆμ§€λ§Œ yajra yajra / laravel-datatables-buttons : ^ 3.1 아직 Laravel / Excel을 μ§€μ›ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ : 3.0
https://laravel-excel.maatwebsite.nl/docs/3.0/export/queued

μΏΌλ¦¬μ—μ„œ 직접 λ‚΄λ³΄λ‚΄κ±°λ‚˜ 웅변적인 방법이 μžˆμ–΄μ•Όν•©λ‹ˆλ‹€.

Postman을 μ‚¬μš©ν•˜μ—¬ ν•΄λ‹Ή μž‘μ—…μ„ λͺ¨λ°©ν•˜μ§€λ§Œ

134217728 λ°”μ΄νŠΈμ˜ ν—ˆμš© 된 λ©”λͺ¨λ¦¬ 크기가 μ†Œμ§„λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

μ˜ˆμ™Έκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. html을 μƒμ„±ν•˜λŠ” 데 μ‚¬μš© 된 행이없고 rawColumns ()λ₯Ό μ‚¬μš©ν•˜μ—¬ html을 μ΄μŠ€μΌ€μ΄ν”„ μ²˜λ¦¬ν•©λ‹ˆλ‹€. λ‚΄ μΏΌλ¦¬λŠ” phpmyadminμ—μ„œ 0.420ms, μ²˜μŒμ—λŠ” 1.4 μ΄ˆκ°€ κ±Έλ¦½λ‹ˆλ‹€.

이것을 λŒ€κΈ°μ—΄μ— 넣을 수 μžˆλ‹€λ©΄ μ„œλ²„μ˜ 폴더에 μ €μž₯ ν•œ λ‹€μŒ μ‚¬μš©μžμ—κ²Œ λ‹€μš΄λ‘œλ“œ ν•  μˆ˜μžˆλŠ” 링크λ₯Ό 제곡 ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

응닡 ν•΄ μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€.

JQuery Datatable λ˜λŠ” yajra datatableμ—μ„œ μ‚¬μš©ν•˜κ³  있으며 μ„œλ²„ μΈ‘μ—μ„œ 내보내고 μ‹ΆμŠ΅λ‹ˆλ‹€.

μ„œλ²„μ˜ 폴더에 μ €μž₯ν•˜λŠ” 것이 λΆˆκ°€λŠ₯ν•˜λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. 문제λ₯Ό μΌμœΌν‚€λŠ” λ§Žμ€ λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€.

데이터 슀트리밍이 ν•„μš”ν•©λ‹ˆλ‹€.

데이터 양은 μ‘λ‹΅μœΌλ‘œ 20MB μ΄μƒμž…λ‹ˆλ‹€.

λ‚΄ μš”κ΅¬ 사항은 λΉ„μŠ·ν•˜μ§€λ§Œ νŒŒμΌμ„ μ„œλ²„ (λ˜λŠ” S3)에 μ €μž₯ν•˜κ³  λ‚΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λŒ€μ‹œ λ³΄λ“œ λ˜λŠ” μ΄λ©”μΌμ—μ„œ λ‹€μš΄λ‘œλ“œ ν•  μˆ˜μžˆλŠ” 링크λ₯Ό μ œκ³΅ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. μ—¬κΈ°μ—μ„œ μ—…λ°μ΄νŠΈ ν•  λ‚΄μš©μ„ 찾으면이 μž‘μ—…μ„ μˆ˜ν–‰ ν•  κ°€λŠ₯성이 μžˆμŠ΅λ‹ˆλ‹€.

λ§Žμ€ μ–‘μ˜ λž¨μ„ μ†ŒλΉ„ν•˜κ³  κΈ°λ³Έ 슀크립트 λ©”λͺ¨λ¦¬ ν• λ‹Ή 크기가 60MB 인 μ„œλ²„ μΈ‘ μ²˜λ¦¬μ— λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€.
php.ini의 memory_limit μ‚΄νŽ΄λ³΄κΈ°
μ‹€ν–‰ μ‹œκ°„ μ œν•œ max_execution_time 은 60μž…λ‹ˆλ‹€.
값을 늘린 ν›„ μ„œλ²„ μΈ‘ 내보내기λ₯Ό μ‚¬μš©ν•˜μ—¬ μš”μ²­ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ‹€μš΄λ‘œλ“œ λŒ€μ‹  νŒŒμΌμ„ μ €μž₯ν•˜λ„λ‘ μ—‘μ…€ κΈ°λŠ₯을 μˆ˜μ •ν–ˆλŠ”λ°, νŒŒμΌμ„ storage / exports / 폴더에 μ €μž₯ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

public function excel()
{
    $this->buildExcelFile()->store('xls');
}

ν˜„μž¬ λ‚΄ 개발 ν™˜κ²½μ— λ§Žμ€ μ–‘μ˜ 데이터가 μ—†μŠ΅λ‹ˆλ‹€. μœ„μ˜ 섀정을 λ³€κ²½ν•˜κ³  λ©”λͺ¨λ¦¬ 캑에 λ„λ‹¬ν•˜μ§€ μ•Šκ³  ν•΄λ‹Ή ν΄λ”μ—μ„œ Excel을 λ§Œλ“€ 수 μžˆλŠ”μ§€ 확인할 수 μžˆμŠ΅λ‹ˆκΉŒ?

μ£Όλͺ©ν•΄μ•Ό ν•  또 λ‹€λ₯Έ 사항은 Laravel 5.1을 μ‚¬μš©ν•˜κ³  μžˆμœΌλ―€λ‘œ maatwebsite / excel 버전 2.1을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

μ œκ°€ μ •λ§λ‘œν•˜κ³  싢은 것은 이것을 λŒ€μ‹  λŒ€κΈ°μ—΄μ— λ„£κ³  λ³΄κ³ μ„œ μž‘μ„±μ΄ 진행 μ€‘μ΄λΌλŠ” λ©”μ‹œμ§€μ™€ ν•¨κ»˜ νŽ˜μ΄μ§€λ‘œ λŒμ•„κ°€μ„œ νŒŒμΌμ„ λ‹€μš΄λ‘œλ“œ ν•  μˆ˜μžˆλŠ” 링크가 등둝 된 ID둜 μ „μ†‘λ˜λŠ” κ²ƒμž…λ‹ˆλ‹€. "

2.1 λ²„μ „μ—μ„œλŠ” μ–΄λ–»κ²Œ λŒ€κΈ°μ—΄μ— 넣을지 λͺ¨λ₯΄κ² μ§€λ§Œ "

κ·Έλž˜μ„œ 이것에 λŒ€ν•œ μ—…λ°μ΄νŠΈκ°€ μžˆμŠ΅λ‹ˆκΉŒ?

κ·Έλž˜μ„œ 이것에 λŒ€ν•œ μ—…λ°μ΄νŠΈκ°€ μžˆμŠ΅λ‹ˆκΉŒ?

Laravel Excel 3.0 이상을 μ‚¬μš©ν•˜λŠ” μ‚¬λžŒμ€ μƒμœ„ μ†”λ£¨μ…˜μ΄ μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ "Queued Export"λ₯Ό μ‚¬μš©ν•˜μ—¬ buildExcelFile() λ₯Ό μž¬μ •μ˜ν•΄μ•Όν•©λ‹ˆλ‹€.

μ•„λ‹ˆλ©΄ λ‚΄κ°€ λ˜ν•œ 청크 μ‚¬μš©ν•˜μ§€λ§Œ λ‚΄ 일을 λ‚΄ νŠΉμ„± 및 μ‚¬μš© CSVλ₯Ό μž‘μ„±ν•˜μ—¬ λ‹€λ₯Έ λ­”κ°€λ₯Όν–ˆκ³ ,이 예

μ–΄λ–€ μ—…λ°μ΄νŠΈ?

Laravel 6λΆ€ν„°λŠ” LazyCollectionsλ₯Ό μ‚¬μš©ν•˜μ—¬ ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ ν•­λͺ© 만 λ©”λͺ¨λ¦¬μ—λ‘œλ“œ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이것은 λ©”λͺ¨λ¦¬ λΆ€μ‘± 문제λ₯Ό ν•΄κ²°ν•©λ‹ˆλ‹€.

DataTable 클래슀λ₯Ό ν™•μž₯ν•˜κ³  μ‘°μ • 된 DataTablesExportHandlerλ₯Ό μž‘μ„±ν•˜κΈ° λ§Œν•˜λ©΄λ©λ‹ˆλ‹€.

λ‚΄ μš”μ  확인

즐겨!

@singhofmarco 예제λ₯Ό λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆκΉŒ?

@singhofmarco λ™μ˜ν•©λ‹ˆλ‹€. μž‘λ…„μ— LazyCollectionsλ₯Ό ν™œμš©ν•  v10 ν”„λ‘œμ νŠΈλ₯Ό μ‹œμž‘ν–ˆμ§€λ§Œ atm을 계속할 μˆ˜λŠ” μ—†μŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” λ‹€λ₯Έ 길을 κ°”λ‹€. csv ν•¨μˆ˜λ₯Ό μž¬μ • μ˜ν•˜μ—¬ 맀번 ν•œ νŽ˜μ΄μ§€μ˜ λ°μ΄ν„°λ‘œ DataTablesλ₯Ό ν˜ΈμΆœν•˜μ—¬ 효과적으둜 μ²­ν‚Ήν–ˆμŠ΅λ‹ˆλ‹€. 파일이 μ™„λ£Œ 될 λ•ŒκΉŒμ§€ κ²°κ³Ό 행에 fputcsv λ₯Ό μ‚¬μš©ν•œ λ‹€μŒ 파일 λ‚΄μš©μ„ Laravel 응닡에 λ°˜ν™˜ν•©λ‹ˆλ‹€.

λ©”λͺ¨λ¦¬ μ œν•œμ— 더 이상 λ„λ‹¬ν•˜μ§€ μ•Šμ„λΏλ§Œ μ•„λ‹ˆλΌ (CSV μžμ²΄κ°€ PHP λ©”λͺ¨λ¦¬ μ œν•œμ„ 초과 ν•  λ•ŒκΉŒμ§€ 슀트리밍 응닡이 더 도움이 될 수 있음) 두 λ°° 이상 λΉ λ¦…λ‹ˆλ‹€.

@ameenross κ°€λŠ₯ν•˜λ‹€λ©΄ μ½”λ“œλ₯Ό κ³΅μœ ν•΄μ£Όμ„Έμš”.

@karmendra Yajra Datatables의 이전 버전이기 λ•Œλ¬Έμ— μ›ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ 기본적으둜 λ‚΄κ°€ν•˜λŠ” 일은 μš”μ²­μ—μ„œ 일뢀 νŽ˜μ΄μ§€ 길이 값을 λ³‘ν•©ν•˜κ³  일반적으둜 AJAX에 λŒ€ν•œ 데이터 νŽ˜μ΄μ§€λ₯Ό λ°˜ν™˜ν•˜λŠ” μ½”λ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€ (제 경우 $this->ajax()->getData(true)['data'] ). getCsv ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ Yajra Datatable 클래슀λ₯Ό ν™•μž₯ν•˜λŠ” 데이터 ν…Œμ΄λΈ”μ— λŒ€ν•œ κΈ°λ³Έ ν΄λž˜μŠ€κ°€ μžˆμŠ΅λ‹ˆλ‹€ (κ²°κ΅­ CSV ν•¨μˆ˜λ₯Ό μž¬μ •μ˜ν•˜μ§€ μ•ŠκΈ°λ‘œ κ²°μ •ν–ˆμ§€λ§Œ μ€‘μš”ν•˜μ§€ μ•ŠμŒ). 더 이상 남은 νŽ˜μ΄μ§€κ°€ 없을 λ•ŒκΉŒμ§€ λ°˜λ³΅λ©λ‹ˆλ‹€.

@ameenross 도움이 λ˜μ…¨μŠ΅λ‹ˆλ‹€. λ‚˜λŠ” 이것을 μ‹œλ„ ν•  것이닀.

라 라벨 데이터 ν…Œμ΄λΈ” :: v1.5.0
@TheGeekyM λŒ“κΈ€μ„ 기반으둜 ν•œ λ‚΄ μ†”λ£¨μ…˜μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€. λ‹€λ₯Έ μ‚¬λžŒμ—κ²Œ 도움이 될 수 μžˆλ„λ‘ 남겨 λ‘‘λ‹ˆλ‹€.
FromQueryλ₯Ό κ΅¬ν˜„ν•˜λŠ” ChunkedDatatableExportHandler 클래슀λ₯Ό λ§Œλ“  λ‹€μŒ ServiceDataTablesμ—μ„œ buildExcelFile λ©”μ„œλ“œλ₯Ό μž¬μ • μ˜ν•˜μ—¬ μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€.

<?php

namespace App\DataTables;

use Yajra\DataTables\Services\DataTable;

class ServiceDataTable extends DataTable
{
  protected $exportClass = ChunkedDatatableExportHandler::class;

  protected function buildExcelFile()
  {
      $query = app()->call([$this, 'query']);
      $query = $this->applyScopes($query);

      $dataTable = app()->call([$this, 'dataTable'], compact('query'));
      $dataTable->skipPaging();
      $data_query = $dataTable->getFilteredQuery();

      return new $this->exportClass($data_query);
  }
}
<?php
namespace App\DataTables;

use Illuminate\Database\Query\Builder;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadings;

class ChunkedDatatableExportHandler implements FromQuery, WithHeadings
{
    use Exportable;

    /**
     * <strong i="11">@var</strong> Builder 
     */
    protected $query;

    /**
     * ChunkDatatablesExportHandler constructor.
     * <strong i="12">@param</strong> Builder $query
     */
    public function __construct(Builder $query)
    {
        $this->query = $query;
    }

    /**
     * <strong i="13">@return</strong> array
     */
    public function headings(): array
    {
        $first = $this->query()->first();

        if ($first) {
            return array_keys((array)$first);
        }

        return [];
    }

    /**
     * <strong i="14">@return</strong> Builder
     */
    public function query()
    {
        return $this->query;
    }
}
이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰