我从数据库加载数据时遇到问题,系统报错
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>
请显示生成 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');
}
如果您有 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
表中,您可以使用上面的查询跳过它们以提高效率。
您可以使用分页来加载少量数据,而不是一次加载所有数据。
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