Chunk on Laravel 4.2 using lots of memory

Asked

Viewed 96 times

0

I am using in an application a query to get data from a table and then generate a file xlsx. The problem is that it returns a lot of information, about 1,5 GB. As a solution, so I’m using the method chunk() of Query Builder of Laravel 4.2, but it was still using a lot of memory in the application. I then tried to remove the variables from memory for each query in the database using unset(), still using a lot of memory.

Follow the method obtaining the information from the base:

<?php
    $urlTeste = '';
    $indiceRelatorios = 0;
    class RelatorioJob {

        public function relatorioPadrao ($job, $data)
        {

$padrao = \VW_RelatorioPadrao::whereBetween('DTALTERACAO',array($dataInicial, $dataFinal))
                ->chunk(1000, function($resultados){
                    global $indiceRelatorios;

                    $padraoFormatado = \RelatorioPadraoConverter::modelsToReport($resultados);

                    //array de padroes diferentes de cancelado e diferente de desativado
                    $naoCancelados = [];
                    // criar um array de padroes cancelados (unicos)
                    $cancelados = [];

                    if(!empty($padraoFormatado)){
                        foreach($padraoFormatado as $v){
                            if($v->status == StatusAprovacao::cancelado){
                                $isExist = false;
                                foreach ($cancelados as $c){
                                    if($c->identificador == $v->identificador){
                                        $isExist = true; break;
                                    }
                                }
                                if(!$isExist){
                                    $cancelados[] = $v;
                                }
                            } else if($v->status != StatusAprovacao::desativado) {
                                $naoCancelados[] = $v;
                            }
                        }
                    }

                     /* INICIO: Cria diretório e pasta com arquivo */
                    $nomeArqTeste = 'padraoTeste' . $indiceRelatorios . '.xlsx';

                    if(! \File::isDirectory($GLOBALS['urlTeste'])){
                        $teste = \File::makeDirectory($GLOBALS['urlTeste'], 0775, true);
                    }
                    // Teste salvar arquivo
                    $arqTeste = \File::put($GLOBALS['urlTeste'] . $nomeArqTeste, 'Apenas um teste');
                    if ($arqTeste === false){
                        \Log::info('Erro ao salvar arquivo!');
                    }
                    /* FIM: Cria diretório e pasta com arquivo */

                    // Para gravar na pasta
                    $padraoTemplate = new RelatorioPadraoTemplate2();

                    $padraoTemplate->adicionarItemVisualizado($naoCancelados);

                    $padraoTemplate->adicionarItemAplicabilidadePadrao($naoCancelados);

                    $padraoTemplate->adicionarItemPadraoCancelado($cancelados);

                    $this->setHeaderFileName($padraoTemplate->getGeneratedFinalFilename($nomeArqTeste));

                    $padraoTemplate->saveSpreadSheet($GLOBALS['urlTeste'] . $nomeArqTeste);

                    // Avaliar uso de memória
                    \Log::info('Fim da solicitação de Relatório Padrão');
                    \Log::info('Uso de memória: '. (memory_get_usage(true)/1024/1024) . ' MB');

                    $indiceRelatorios++ ;

                    unset($padraoFormatado);
                    unset($naoCancelados);
                    unset($cancelados);
                    unset($padraoTemplate);

                });

Memory usage for 18000 lines remained:

[2016-12-09 12:02:11] production.INFO: Inicio da JOB [] []
[2016-12-09 12:02:11] production.INFO: Uso de memória: 6 MB [] []
[2016-12-09 12:02:35] production.INFO: Uso de memória: 74.5 MB [] []
[2016-12-09 12:03:02] production.INFO: Uso de memória: 115.5 MB [] []
[2016-12-09 12:03:30] production.INFO: Uso de memória: 148.75 MB [] []
[2016-12-09 12:03:59] production.INFO: Uso de memória: 199.5 MB [] []
[2016-12-09 12:04:27] production.INFO: Uso de memória: 232.25 MB [] []
[2016-12-09 12:04:52] production.INFO: Uso de memória: 266 MB [] []
[2016-12-09 12:05:21] production.INFO: Uso de memória: 298 MB [] []
[2016-12-09 12:05:50] production.INFO: Uso de memória: 363.25 MB [] []
[2016-12-09 12:06:18] production.INFO: Uso de memória: 397.5 MB [] []
[2016-12-09 12:06:47] production.INFO: Uso de memória: 430 MB [] []
[2016-12-09 12:07:16] production.INFO: Uso de memória: 463.5 MB [] []
[2016-12-09 12:07:44] production.INFO: Uso de memória: 496.75 MB [] []
[2016-12-09 12:08:17] production.INFO: Uso de memória: 530.5 MB [] []
[2016-12-09 12:08:49] production.INFO: Uso de memória: 563.5 MB [] []
[2016-12-09 12:09:20] production.INFO: Uso de memória: 697.5 MB [] []
[2016-12-09 12:09:54] production.INFO: Uso de memória: 696.5 MB [] []
[2016-12-09 12:10:27] production.INFO: Uso de memória: 727 MB [] []
[2016-12-09 12:11:01] production.INFO: Uso de memória: 761 MB [] []
[2016-12-09 12:11:36] production.INFO: Uso de memória: 785.75 MB [] []

I am running out of alternatives as to what I may be doing to solve the problem. I thank you all for your attention.

  • The problem is file size or memory usage?

  • @geekcom is memory usage, if I run an application like this on a server with memory limitation my application will break

1 answer

0

In any case if you need to make the generated file smaller use the Ziparchive class which is a native class of PHP itself as follows:

$diretorio = getcwd() . '/pasta_teste/';
$zip = new ZipArchive();
if($zip->open('nome_arquivo_zip.zip', ZIPARCHIVE::CREATE) == TRUE){    
      $zip->addFile($diretorio . 'arquivo1.txt', 'arquivo1.txt');
      $zip->addFile($diretorio . 'arquivo2.txt', 'arquivo2.txt');
      echo 'Arquivo criado com sucesso.';
}else{
   exit('O Arquivo não pode ser criado.');
}
$zip->close();

Browser other questions tagged

You are not signed in. Login or sign up in order to post.