如何优化从数据库中获取数据以进行 PDF 转换

问题描述 投票:0回答:3

我从数据库加载数据时遇到问题,系统报错

Maximum Execution time off 60 seconds exceeded

我意识到我需要优化我的代码以缩短加载数据的时间,我的表中几乎有 10K 的数据。

这是我的代码

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');

}

请帮我优化这段代码,我不知道我应该怎么做才能优化这段代码。 提前谢谢你

更新 这是我的查看代码

<!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>
laravel dompdf
3个回答
1
投票

请显示生成 pdf 的视图,当我尝试使用一些 Laravel 辅助函数时遇到同样的问题(在我的例子中,我尝试使用

asset()
函数)。

尝试使用

loop
变量代替
$i
变量

<tr>
 <th>{{$loop->index}}</th>
 <td>{{$fotoOutcome->name}}</td>
 <td>{{$fotoOutcome->date}}</td>
 <td>{{$fotoOutcome->pcs}}</td>
 <td>{{$fotoOutcome->cost}}</td>
</tr>

或者您可以使用较少的数据进行测试,如果失败,则错误在视图中

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

}

1
投票

如果您有 10K 个项目,那么您将在该查询中混合 ton 模型。这需要时间和记忆。减少这种情况的最有效方法可能是使用

DB
查询而不是完全水化模型。假设你的桌子是
foto_outcomes

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

但是,这仍然是从该表中提取所有信息。您可以通过不选择

*
并仅应用您需要的字段来进一步减少查询时间:

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

我看到您在原始查询中包含了三个关系。如果有必要,您必须将它们添加到上述查询中。您还可以为这些关系添加 select 语句,以节省对这些关系的调用

*
。但是,如果这些项目在原始
foto_outcomes
表中,您可以使用上面的查询跳过它们以提高效率。


0
投票

您可以使用分页来加载少量数据,而不是一次加载所有数据。

public function export(Request $request){
    $pageSize = 100; // set the number of records to load per page
    $fotoOutcomes = FotoOutcome::with('user', 'outcomeCategory', 'paymentMethod')
        ->select('name', 'cost', 'date', 'pcs')
        ->paginate($pageSize); // use pagination to load data in smaller chunks
    $fotoOutcomes = new FotoOutcomeCollection($fotoOutcomes);
    $pdf = PDF::loadView('FotoOutcomeExport/FotoOutcomeExport', compact('fotoOutcomes'));
    return $pdf->download('Foto-Outcome.pdf');
}

您可以在视图代码中像这样更改您的 for 循环。

@foreach ($fotoOutcomes as $fotoOutcome)
<tr>
    <th>{{ $fotoOutcomes->firstItem() + $loop->index }}</th>
    <td>{{ $fotoOutcome->name }}</td>
    <td>{{ $fotoOutcome->date }}</td>
    <td>{{ $fotoOutcome->pcs }}</td>
    <td>{{ $fotoOutcome->cost }}</td>
</tr>
@endforeach
© www.soinside.com 2019 - 2024. All rights reserved.