Search code examples
laraveldompdf

How to optimize fetching data from database for PDF Convertion


i have a problem to load the data from database , the system give me an error

Maximum Execution time off 60 seconds exceeded

i realize i need to optimze my code to shrink the time to load the data, I nearly have 10K of data in the table.

this is my code

public function export(Request $request){
    $fotoOutcomes= new FotoOutcomeCollection(FotoOutcome::with('user','outcomeCategory','paymentMethod')->select('name','cost','date','pcs')->get());  
    $pdf = PDF::loadView('FotoOutcomeExport/FotoOutcomeExport', compact('fotoOutcomes'));
    return $pdf->download('Foto-Outcome.pdf');

}

please help me to optimize this code, i have no idea about what should i do to optimize this code. thankyou in advance

UPDATE this is my view code

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>

</head>
<body>
<div className="overflow-x-auto">
    <table className="table table-zebra w-full">
        <thead>
            <tr>
                <th>No</th>
                <th>Name</th>
                <th>Date</th>
                <th>Pcs</th>
                <th>Cost</th>
            </tr>
        </thead>
        <tbody>
            @php $i=1 @endphp
            @foreach ($fotoOutcomes as $fotoOutcome)
            
            <tr>
                <th>{{$i}}</th>
                <td>{{$fotoOutcome->name}}</td>
                <td>{{$fotoOutcome->date}}</td>
                <td>{{$fotoOutcome->pcs}}</td>
                <td>{{$fotoOutcome->cost}}</td>
            </tr>
            @php $i++; @endphp
            @endforeach
        </tbody>
    </table>
</div>

Solution

  • If you have 10K of items, you are hydrating a ton of models in that query. That takes time and memory. Probably the most efficient way to reduce this would be to use a DB query and not fully hydrate the models. Assuming your table is foto_outcomes:

    $fotoOutcomes = \DB::table('foto_outcomes')->get();
    

    However, this is still pulling in all of the information from that table. You can further reduce the query time by not selecting *, and only applying the fields you need:

    $fotoOutcomes = \DB::table('foto_outcomes')->select('name', 'date', 'pcs', 'cost')->get();
    

    I see you have included three relationships in your original query. If those are necessary, you will have to add them to the above query. You can also add a select statement for those relations to save calling * on those relations. However, if those items are on the original foto_outcomes table, you can skip them for a big jump in efficiency, using the query above.