查询需要很长时间才能执行 laravel
Query takes to much time to execute laravel
我正在上传一个 excel 文件,其中包含用户数据及其产品状态 (0,1)。
我想先在 Productsale table 中保存产品数据,其中 user_id、product_id、target_month 和状态。
然后我获取所有用户,然后从 productsale table 获取产品及其状态并计算它并将其结果保存在 Saleproduct table。
我在 excel 文件中有 33000 行并在产品销售中节省了 300k,boz everyuser 有 8 个产品,
这里是excel的SS
这是我的代码
try {
$path = $request->file('file')->store('upload', ['disk' => 'upload']);
$value = (new FastExcel())->import($path, function ($line) {
$user = User::where('code', $line['RVS Code'])->first();
$store = Store::where('code', $line['Customer Code'])->first();
$a = array_keys($line);
$total_number = count($a);
$n = 4;
$productsale= 0;
for ($i=3; $i<$total_number; $i++) {
$str_arr = preg_split('/(ml )/', $a[$i]);
$product = Product::where('name', $str_arr[1] ?? null)->where('type', $str_arr[0] . 'ml')->first();
if (!empty($product)) {
$product = ProductSale::updateOrCreate([
'user_id' => $user->id,
'store_id' => $store->id,
'month' => $line['Target Month'],
'product_id' => $product->id,
'status' => $line[$str_arr[0] . 'ml ' . $str_arr[1]],
]);
}
}
});
//sales
$datas = User::all();
foreach($datas as $user){
$targets = Target::where('user_id',$user->id)->get();
foreach($targets as $target){
$sales = Sales::where('user_id', $user->id)->where('month',$target->month)->first();
$products = Product::all();
foreach ($products as $product) {
$totalSale = ProductSale::where('user_id',$user->id)->where('month',$target->month)->where('product_id',$product->id)->sum('status');
$sale_product = SalesProduct::updateOrCreate([
'product_id' => $product->id,
'sales_id' => $sales->id,
'sale' => $totalSale,
]);
}
}
}
return response()->json(true, 200);
}
如果 运行 花费的时间太长(并且可能会导致返回错误),则不要同步执行 - 即。当用户正在等待时 - 但它是异步的。
您的控制器应该只关心验证文件,将其保存到存储中,并将成功代码返回给用户,告诉他们文件已经上传,很快就会处理。
然后将所有关于文件处理的代码移动到控制器调度的作业中,运行在后台进行。理想情况下,这将在队列中(在这种情况下,请查看您的队列设置,因为默认情况下作业在 30 秒内完成,这与您可能已经违反的 PHP 设置一致,所以准备好让作业执行更长的时间)。
您正在请求从您的“糟糕的数据库:(”针对每个用户的每个目标的每个产品进行单独的查询。
- 尝试实现产品、销售、用户、目标之间的关系,并在获取用户时预先加载它们
- 小心你在每个循环中做的每一个查询
- 获取您的最终查询并在您的数据库中使用 EXPLAIN 命令来分析在后端执行您的代码时会发生什么。
- active DB慢查询日志获取然后优化。
- 将您的数据库 table 引擎更改为 MyISAM。
您可以做很多其他事情来优化您的查询。
我正在上传一个 excel 文件,其中包含用户数据及其产品状态 (0,1)。
我想先在 Productsale table 中保存产品数据,其中 user_id、product_id、target_month 和状态。
然后我获取所有用户,然后从 productsale table 获取产品及其状态并计算它并将其结果保存在 Saleproduct table。
我在 excel 文件中有 33000 行并在产品销售中节省了 300k,boz everyuser 有 8 个产品,
这里是excel的SS
这是我的代码
try {
$path = $request->file('file')->store('upload', ['disk' => 'upload']);
$value = (new FastExcel())->import($path, function ($line) {
$user = User::where('code', $line['RVS Code'])->first();
$store = Store::where('code', $line['Customer Code'])->first();
$a = array_keys($line);
$total_number = count($a);
$n = 4;
$productsale= 0;
for ($i=3; $i<$total_number; $i++) {
$str_arr = preg_split('/(ml )/', $a[$i]);
$product = Product::where('name', $str_arr[1] ?? null)->where('type', $str_arr[0] . 'ml')->first();
if (!empty($product)) {
$product = ProductSale::updateOrCreate([
'user_id' => $user->id,
'store_id' => $store->id,
'month' => $line['Target Month'],
'product_id' => $product->id,
'status' => $line[$str_arr[0] . 'ml ' . $str_arr[1]],
]);
}
}
});
//sales
$datas = User::all();
foreach($datas as $user){
$targets = Target::where('user_id',$user->id)->get();
foreach($targets as $target){
$sales = Sales::where('user_id', $user->id)->where('month',$target->month)->first();
$products = Product::all();
foreach ($products as $product) {
$totalSale = ProductSale::where('user_id',$user->id)->where('month',$target->month)->where('product_id',$product->id)->sum('status');
$sale_product = SalesProduct::updateOrCreate([
'product_id' => $product->id,
'sales_id' => $sales->id,
'sale' => $totalSale,
]);
}
}
}
return response()->json(true, 200);
}
如果 运行 花费的时间太长(并且可能会导致返回错误),则不要同步执行 - 即。当用户正在等待时 - 但它是异步的。
您的控制器应该只关心验证文件,将其保存到存储中,并将成功代码返回给用户,告诉他们文件已经上传,很快就会处理。
然后将所有关于文件处理的代码移动到控制器调度的作业中,运行在后台进行。理想情况下,这将在队列中(在这种情况下,请查看您的队列设置,因为默认情况下作业在 30 秒内完成,这与您可能已经违反的 PHP 设置一致,所以准备好让作业执行更长的时间)。
您正在请求从您的“糟糕的数据库:(”针对每个用户的每个目标的每个产品进行单独的查询。
- 尝试实现产品、销售、用户、目标之间的关系,并在获取用户时预先加载它们
- 小心你在每个循环中做的每一个查询
- 获取您的最终查询并在您的数据库中使用 EXPLAIN 命令来分析在后端执行您的代码时会发生什么。
- active DB慢查询日志获取然后优化。
- 将您的数据库 table 引擎更改为 MyISAM。
您可以做很多其他事情来优化您的查询。