【问题标题】:My Laravel Code running slow because foreach, should i change my query to chunk? and how to optimize it?由于 foreach,我的 Laravel 代码运行缓慢,我应该将查询更改为块吗?以及如何优化它?
【发布时间】:2022-01-17 17:36:53
【问题描述】:

这个概念很简单,我想从具有相同工作名称的表分析中总结一些名为 total_hs 的值。由于 foreach if 有很多数据,这段代码运行速度很慢。

public function totalHSBySameName()
    {

        $result = Analysis::selectRaw('workingname')->get();

        $name = [];
        $total = [];
        
        foreach ($result as $i) {
            if (!in_array($i->workingname, $name)) {
                $name[] = $i->workingname;
            }
        }
        foreach ($name as $i) {
            $temp = 0;
            $x = Analysis::selectRaw('workingname,total_hs')
            ->where('workingname', $i)
            ->get();
            foreach ($x as $j) {
                $temp += $j->total_hs;
            }
            $total[] = ["name" => $i, 'total_hs' => $temp];
        }
        return $total;
    }

对于这样的模型

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Analysis extends Model
{
    use HasFactory;

    protected $analysis;
    public $table = 'analysis';
    const CREATED_AT = 'created_at';
    const UPDATED_AT = 'updated_at';
    protected $fillable = [
        'workingname',
        'code',
        'koef',
        'total_hs',
        'created_by',
        'updated_by',
    ];
}

【问题讨论】:

  • 你不能在查询构建器上使用 groupBy 和 sum 吗?我认为这应该给你正确的 wjat 你需要从数据库中获得海峡。见laravel.com/docs/8.x/queries#aggregates
  • 你为什么不试试->unique('workingname')
  • 由于某种原因我需要在数据库之外求和,工作名称可以重复,但它在代码列中具有不同的值
  • 如果由于某种原因无法对数据库执行sum 操作,并且由于涉及的数据量,在 PHP 中执行该操作需要一段时间,请考虑使用queue .
  • 你可以跳过这个条件:if (!in_array($i->workingname, $name)) {,然后使用array_unique($name)一次。它可能会加快一点。我还会尝试使用INimplode all workingname 运行一个查询。但是如果$name有很多元素,可能需要增加一些数据库设置(max_allowed_packetstackoverflow.com/questions/4275640/mysql-in-condition-limit)。

标签: php laravel chunks


【解决方案1】:

如果我理解,您想为每个 workingname 返回 total 值。 您可以用我在下面提到的新功能替换您的功能。所以,这可能会有所帮助:

public function totalHSBySameName() {
        $result = Analysis::groupBy('workingname')
            ->selectRaw('sum(total_hs) as sum, workingname')
            ->pluck('sum','workingname');

        return $result;
}

【讨论】:

  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
【解决方案2】:

试试这个

public function totalHSBySameName()
    {
        $total = Analysis::query()
            ->groupBy('workingname')
            ->selectRaw('sum(total_hs) as sum, workingname')
            ->pluck('sum', 'workingname');
        return $total;
    }

【讨论】:

    猜你喜欢
    • 2019-12-02
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多