You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 8中getCasts重复调用致性能下降,求优化方案

Laravel 8中CompanyRounds模型getCasts()高频调用的性能优化方案

针对查询363条CompanyRounds数据时getCasts()被调用5904次导致的性能问题,结合你依赖casts和appends的业务需求,提供以下优化方案:

1. 缓存casts计算结果到模型实例

默认getCasts()每次调用都会合并父类casts并重新计算,重写该方法将结果缓存到实例属性,每个模型实例仅计算一次:

protected $cachedCasts;

public function getCasts()
{
    if (!isset($this->cachedCasts)) {
        $this->cachedCasts = parent::getCasts();
    }
    return $this->cachedCasts;
}

2. 按需加载appends字段

避免全局加载所有appends,根据业务场景动态控制:

  • 查询时临时禁用不必要的appends,后续手动添加需要的字段:
    $rounds = CompanyRounds::withoutAppends()->get();
    // 仅对需要的模型实例添加特定appends字段
    foreach ($rounds as $round) {
        $round->append(['funding_amount', 'investor_count']);
    }
    
  • 定义查询作用域,只加载业务必需的appends:
    public function scopeWithCoreAppends($query)
    {
        return $query->setAppends(['funding_amount', 'investor_count']);
    }
    
    // 使用时
    $rounds = CompanyRounds::withCoreAppends()->get();
    

3. 转换为数组后处理数据

将模型集合转为数组,一次性处理casts和appends,后续操作数组避免反复触发模型方法:

// 先转换为数组,减少模型属性访问次数
$roundsArray = CompanyRounds::get()->toArray();

foreach ($roundsArray as $round) {
    // 直接操作数组元素,不再触发getCasts()
    $processedData[] = [
        'id' => $round['id'],
        'funding_amount' => $round['funding_amount'],
        'investor_list' => $round['investor_list']
    ];
}

4. 优化属性访问逻辑

减少循环中对模型属性的重复访问,使用only()方法批量获取所需属性:

$processedData = CompanyRounds::get()->map(function ($round) {
    // 一次性获取需要的属性集合
    return $round->only(['id', 'funding_amount', 'investor_count']);
});

5. 应用Laravel 8最新补丁

Laravel 8的后续补丁版本对模型casts的缓存逻辑有优化,升级到同版本的最新补丁包,可直接享受框架层面的性能提升。

内容的提问来源于stack exchange,提问作者vok7777

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:25:55