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

Laravel 9+中firstOrCreate()与先查后创建哪个性能更优?

Laravel 9+ 处理40万条记录时,两种方案的性能对比

在Laravel 9+环境下处理约40万条记录时,以下两种实现方式哪种性能更优?我猜测第二种方案性能更好,是否正确?

第一种方案:使用firstOrCreate

$saleId = SaleNumber::firstOrCreate([
                'sale_number' => $line[10], 
                'sale_date' => $saleDate->format('Y-m-d') 
            ])->id;

第二种方案:手动查询+创建

$saleDate = $saleDate->format('Y-m-d');
$saleNumber = SaleNumber::where('sale_number', $line[10])
     ->where('sale_date', $saleDate)
     ->select('id')
     ->first();
if(!$saleNumber) {
     $saleNumber = new SaleNumber();
     $saleNumber->sale_number = $line[10];
     $saleNumber->sale_date = $saleDate;
     $saleNumber->save();
}
$saleId = $saleNumber->id;

我查看了firstOrCreate的源码实现:

public function firstOrCreate(array $attributes = [], array $values = [])
{
    if (! is_null($instance = $this->where($attributes)->first())) {
        return $instance;
    }

    return tap($this->newModelInstance(array_merge($attributes, $values)), function ($instance) {
        $instance->save();
    });
}

结论:第二种方案性能更优,你的猜测是正确的

核心差异点如下:

  • 查询字段更精简:第二种方案通过select('id')仅查询需要的id字段,而firstOrCreate中的first()会返回模型的所有字段。处理几十万条记录时,减少的数据传输量和模型实例化开销会累积成明显的性能优势。
  • 减少不必要的操作:firstOrCreate内部会执行array_merge($attributes, $values)操作(即便你没传$values参数),而手动创建模型时直接赋值,避免了这一步额外的数组处理开销。

额外注意

无论采用哪种方案,必须给sale_number和sale_date建立联合索引——这是批量处理40万条记录的性能基础。没有索引的话,两种方案都会因为频繁的全表查询变得异常缓慢,性能差异也无从谈起。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 16:37:16