Laravel 5.2中使用Blade的foreach太慢

时间:2018-11-12 20:38:22

标签: php laravel foreach laravel-5.2 laravel-blade

我正在使用Laravel 5.2,并且我的部分响应太慢,我发现在foreach循环中发生了大延迟,每行花费一秒钟,我列出了大约100个寄存器,这使得该站点非常慢。很少见,因为我只显示7列,并且该表总共213行,而该表只有16列。

我该怎么办?这是foreach块。仅在生产环境中运行就需要这么长时间

@foreach($tickets as $ticket)
          <tr>
            <td>
              {{ $ticket->id }}
            </td>
            <td>
              {{ $ticket->creator->worksAt->nombre }}
            </td>
            <td>
              {{ $ticket->patient->toArray()['rut'] }}
            </td>
            <td>
              {{ $ticket->getProcessName() }}
            </td>
            <td>
              {{ $ticket->created_at->format('d M Y') }}
            </td>
            @if ($ticket->getProcessSla() == $ticket->getLatency() )
              <td  class="alert-warning">
            @elseif ($ticket->getProcessSla() < $ticket->getLatency() )
              <td  class="alert-danger">
            @else
              <td  class="alert-success">
            @endif
              {{ $ticket->getLatency() }} días
              (Límite: {{ $ticket->getProcessSla() }})
            </td>
            <td>
              @if ( null !== Auth::user()->roles->find($ticket->getProfileId()) )
                {{ Form::open(array('action'=>'StageController@redirect')) }}
                  {{ Form::hidden('ticket_id', $ticket->cryptId()) }}
                  {{ Form::hidden('process_id', $ticket->cryptProcessId()) }}
                  {{ Form::submit('Iniciar', ['class'=>'btn btn-xs btn-block btn-primary']) }}
                {{ Form::close() }}
              @endif
            </td>
          </tr>
    @endforeach

门票的型号是这个

 <?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use App\Http\Controllers\Controller;
use Crypt;
use DB;

class Ticket extends Model
{


protected $fillable = [
  'patient_id',
  'id_empresa',
  'id_usuario',
  'requiere_clinico',
  'requiere_ept',
  'activo',
  'responsable',

  'ept_id',
  'clinico_id',
  'is_massive',
  'inasistente',

  'creacion_original',
  'ficha_id'

];




/*
 * Relations
 */
public function creator()
{
  return $this->belongsTo('App\User', 'id_usuario');
  //'App\Partner', 'clinical_provider', 'id_client', 'id_provider'
}


public function assignedTo()
{
  return $this->belongsTo('App\User', 'responsable', 'id');
}

public function appointment()
{
  return $this->hasMany('App\Appointment', 'id_ticket');
}

public function annulments()
{
  return $this->hasMany('App\Anullment');
}

public function eptCriteria()
{
  return $this->hasOne('App\EptCriteria');
}


public function patient()
{
  return $this->belongsTo('App\Patient');
}

public function enterprise()
{
  return $this->belongsTo('App\Enterprise', 'id_empresa');
}

public function process(){
  return $this->belongsToMany('App\Process', 'flows', 'id_ticket', 'id_proceso');
}

public function witness(){
  return $this->belongsToMany('App\Witness')->withTimestamps();
}

public function documents()
{
  return $this->hasMany('App\Document', 'id_ticket');
}

public function flows()
{
  return $this->hasMany('App\Flow', 'id_ticket');
}

public function comments()
{
  return $this->hasMany('App\Models\Tickets\Comment', 'ticket_id');
}

/**
 * Esto permite dejar la evidencia de cuando se envió el contacto a las empresas
 * @return [type] [description]
 */
public function enterpriseContacts(){
  return $this->hasMany('App\Enterprisecontact');
}

public function getProcessName(){
  return \App\Process::find($this->process()->max('id_proceso'))->nombre;
}

public function getProcessDescription(){
  return \App\Process::find($this->process()->max('id_proceso'))->descripcion;
}

public function getProfileId(){
return \App\Process::find($this->process()->max('id_proceso'))->id_perfil;
}

public function getProcessSla(){
  return \App\Process::find($this->process()->max('id_proceso'))->sla;
}

public function getLatency(){
  $created = new \Carbon\Carbon($this->created_at);
  return $created->startOfDay()->diffInDays();
}
public function getProcessId(){

  return \App\Process::find($this->process()->max('id_proceso'))->id;
}

public function getClinicalAppointment(){
  return $this->appointment()->where('tipo_citacion', '=', 1)->first()['fecha'];
}


public function cryptProcessId(){
  return  Crypt::encrypt($this->getProcessId());
}

public function cryptId(){
  return  Crypt::encrypt($this->id);
}

public function scopeMassive($query){
  $query->where('activo', 1)
        ->where('is_massive', 1);
}

public function eptTest()
{
  return $this->hasMany('App\EptTest');
}

public function clinicalMovements()
{
  return $this->hasMany('App\Models\MR\Movimiento');
}


 }

1 个答案:

答案 0 :(得分:3)

让我们在这里计算查询和其他操作的次数:

  1. $ticket->creator:查询
  2. creator->worksAt可能是另一个查询(猜测为未提供源代码)
  3. $ticket->patient:查询
  4. $ticket->getProcessName():查询
  5. $ticket->getProcessSla():查询
  6. Auth::user()->roles:查询
  7. $ticket->cryptId():加密
  8. $ticket->cryptProcessId():加密+查询(用于查找过程)

总共:7个查询+每个票证2个加密乘以213行。

相当于 1,491个查询和426种加密。难怪它很慢?不是foreach。

您需要通过eager loadingpagination,持久性存储(用于加密)和备注(而不是在数据库中多次重复查找相同的流程模型)进行优化。