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

Laravel:从API读取数据去重入库及批量保存避免超时方案

API数据批量入库:去重+超时优化方案

现有代码问题

你当前的store方法用循环调用updateOrCreate,每条数据都单独执行数据库操作,数据量大时不仅速度慢,还容易触发超时;另外updateOrCreate用所有字段作为重复判断条件,完全没必要,应该用唯一标识字段(比如API字段,每个API名称理应唯一)来判断重复。

解决思路

1. 确保无重复记录

  • 数据库层面:给apidata表的API字段添加唯一索引,从根源上杜绝重复数据插入。
  • 代码层面:用Laravel的upsert方法,指定唯一键,批量处理数据——既可以插入新数据,也能按需更新已存在的数据。

2. 避免大量数据超时

  • 放弃循环单条操作,改用批量处理逻辑;
  • 数据量极大时,可分块处理(比如每50条一批),降低单次数据库操作压力;
  • 去掉set_time_limit这类临时应急方案,从代码逻辑上解决超时问题。

优化后的代码

public function store()
{
    $client = new Client();
    $response = $client->request('GET', 'https://api.publicapis.org/entries');
    $apidata = json_decode($response->getBody()->getContents(), true);

    // 整理符合入库要求的数据格式
    $records = collect($apidata['entries'])->map(function ($entry) {
        return [
            'API' => $entry['API'],
            'Description' => $entry['Description'],
            'Auth' => $entry['Auth'],
            'HTTPS' => $entry['HTTPS'],
            'Cors' => $entry['Cors'],
            'Link' => $entry['Link'],
            'Category' => $entry['Category']
        ];
    })->toArray();

    // 批量upsert:指定API为唯一判断键,存在则更新指定字段,不存在则插入
    // 前提:数据库的API字段已添加唯一索引
    Apidata::upsert(
        $records,
        ['API'], // 重复判断的唯一键
        ['Description', 'Auth', 'HTTPS', 'Cors', 'Link', 'Category'] // 重复时需要更新的字段
    );

    return redirect()->back()->with('message', '数据保存成功!');
}

超大数据量额外优化

如果API返回上万条级别的数据,用分块处理进一步降低压力:

collect($apidata['entries'])->chunk(50)->each(function ($chunk) {
    $chunkData = $chunk->map(function ($entry) {
        return [
            'API' => $entry['API'],
            'Description' => $entry['Description'],
            'Auth' => $entry['Auth'],
            'HTTPS' => $entry['HTTPS'],
            'Cors' => $entry['Cors'],
            'Link' => $entry['Link'],
            'Category' => $entry['Category']
        ];
    })->toArray();

    Apidata::upsert($chunkData, ['API'], ['Description', 'Auth', 'HTTPS', 'Cors', 'Link', 'Category']);
});

数据库唯一索引迁移代码

执行下面的迁移给API字段加唯一索引:

Schema::table('apidata', function (Blueprint $table) {
    $table->unique('API');
});

内容的提问来源于stack exchange,提问作者S. Radje

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 11:30:59