你能优化这个PHP循环查询代码吗?

你能优化这个PHP循环查询代码吗?,php,mysql,laravel,optimization,query-optimization,Php,Mysql,Laravel,Optimization,Query Optimization,我的Laravel网站出现了一些性能问题。 我发现这是我代码的一部分。 我在一个循环中进行查询,这不应该像我刚刚发现的那样进行。 我不确定如何以最佳方式优化此代码(不更改数据库,因为在项目的这一点上,这并不容易) 我想用foreach$transactionfos来改进这个部分,至少有点像这样,但我现在不确定Laravel的语法: $TransactionFos=ToolTransactionInfo::where('tool\u id',$tool->id) ->其中('date',$date

我的Laravel网站出现了一些性能问题。 我发现这是我代码的一部分。 我在一个循环中进行查询,这不应该像我刚刚发现的那样进行。 我不确定如何以最佳方式优化此代码(不更改数据库,因为在项目的这一点上,这并不容易)

我想用
foreach
$transactionfos
来改进这个部分,至少有点像这样,但我现在不确定Laravel的语法:

$TransactionFos=ToolTransactionInfo::where('tool\u id',$tool->id)
->其中('date',$date)
->仅限(['users']))
//->get();
->全部();
如果(!空($TransactionFos)){
$users=数组和($TRANSACTIONFOS);
}
否则{
$users=0;
}
实际代码:

foreach($data['tools']作为$tool){
//30天用户图形数据
$count=30;
$tool_users_30d[$tool->id]=[];
而($count>0){
$date=Carbon::now()->subDays($count)->格式('Y-m-d');
$TransactionFos=ToolTransactionInfo::其中('tool_id',$tool->id)
->其中('date',$date)
->get();
$users=0;
foreach($TransactionFos作为$TransactionFo){
$users+=$transactionInfo->users;
} 
数组推送($tool\u users\u 30d[$tool->id],$users);
$count--;
}
}
$data['tool\u users\u 30d']=$tool\u users\u 30d;
我希望得到一个数组,其中包含所有工具的列表以及每个30天用户数据的数组,例如:

  • [13] [0]=20
  • [13] [1]=6
  • [13] [2]=24
  • [13] [29]=10

  • [18] [0]=50

  • [18] [1]=11
  • [18] [2]=55
  • [18] [29]=6

(示例图像显示0个用户,因为本地数据库为空,但这就是它的外观)。

您可以做一些事情来帮助加速此过程,以提高性能,并减少对数据库/函数调用的点击

首先,在循环之前,您可以一次提取所有
ToolTransactionInfo
。这将帮助您只进行一次DB拉动。因此,在你的循环之上:

$transactionInfosTotal = ToolTransactionInfo::get();
这将为您提供所需的所有信息。然后,在循环中,您可以执行相同的查询,但对内存中已经存在的集合执行查询(即不返回数据库)

这样,您就可以在循环中获得相同的集合,用于正确的日期和工具,然后您可以执行计算或根据需要移动到数组中。这只会节省数据库命中率/使其更高效、更快

你可以做的另一件事是把时间(碳)调一次。这不是一个巨大的节省,但可能会快一点:。在循环之前,将“now”设置为变量:

$now = Carbon(now);
然后使用存储在循环内变量中的值计算时间计算,因为现在不必返回到方法,它已经在内存中了:

$date = $now->subDays($count)->format('Y-m-d');

HTH

您可以做几件事来帮助加快速度,以提高性能,并减少对数据库/函数调用的点击

首先,在循环之前,您可以一次提取所有
ToolTransactionInfo
。这将帮助您只进行一次DB拉动。因此,在你的循环之上:

$transactionInfosTotal = ToolTransactionInfo::get();
这将为您提供所需的所有信息。然后,在循环中,您可以执行相同的查询,但对内存中已经存在的集合执行查询(即不返回数据库)

这样,您就可以在循环中获得相同的集合,用于正确的日期和工具,然后您可以执行计算或根据需要移动到数组中。这只会节省数据库命中率/使其更高效、更快

你可以做的另一件事是把时间(碳)调一次。这不是一个巨大的节省,但可能会快一点:。在循环之前,将“now”设置为变量:

$now = Carbon(now);
然后使用存储在循环内变量中的值计算时间计算,因为现在不必返回到方法,它已经在内存中了:

$date = $now->subDays($count)->format('Y-m-d');

HTH

您可以将整个算法简化为一个sql查询,类似这样的查询(还没有运行它,它至少需要一些引号…),您只需要通过一次结果来构造目标多维数组

SELECT tool_id, 30 - datediff(now(), date) as "offset", sum(users)
FROM transaction_info
WHERE date >= (date(now()) - interval 30 days) AND date < date(now())
GROUP BY tool_id, 30 - datediff(now(), date)
选择工具id,30-datediff(现在(),日期)作为“偏移量”,求和(用户)
从交易信息
其中日期>=(日期(现在())-间隔30天)和日期<日期(现在())
按工具id分组,30-datediff(现在(),日期)

您可以将整个算法简化为一个sql查询,类似于这样(还没有运行它,它至少需要一些引号…),您只需要通过一次结果来构造目标多维数组

SELECT tool_id, 30 - datediff(now(), date) as "offset", sum(users)
FROM transaction_info
WHERE date >= (date(now()) - interval 30 days) AND date < date(now())
GROUP BY tool_id, 30 - datediff(now(), date)
选择工具id,30-datediff(现在(),日期)作为“偏移量”,求和(用户)
从交易信息
其中日期>=(日期(现在())-间隔30天)和日期<日期(现在())
按工具id分组,30-datediff(现在(),日期)

对slepic的查询是一条出路。它将页面总负载从3.8秒提高到了2.5秒(数据页很重,但仍有一些改进需要完成),但这是我可以改进的两个最重的功能之一。谢谢你和所有其他的建议

以下是我的解决方案:

//30天用户图形数据
//准备数组列表
$loaded_tool_id=[];
foreach($data['tools']作为$tool){
数组推送($loaded\u tool\u id,$tool->id);
}
$count=30;
$now=碳::now()->格式('Y-m-d');
$oldest_date=Carbon::now()->subDays($count)->格式