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

如何高效实现PHP更新40万行级大CSV库存文件的需求?

性能瓶颈分析

你当前代码的耗时核心来自嵌套遍历逻辑:每次遍历主库存的一行数据,都会通过array_search + array_column全量遍历stock-feed数组匹配sku,假设stock-feed有1万条数据,总计算量就是40万 * 1万 = 40亿次操作,效率自然极低。

PHP优化方案

核心优化点是将stock-feed转为以sku为键的关联索引数组,sku匹配从O(n)降到O(1),总时间复杂度降至O(stock-feed行数 + 主库存行数),40万行数据通常可以在3秒内处理完成。
优化后代码如下:

<?php
// 第一步:处理stock-feed生成sku=>库存的映射索引
$feedHandle = fopen('stock-feed.csv', 'r');
$feedHeader = fgetcsv($feedHandle, 0, ',');
$skuStockMap = [];
while (($feedRow = fgetcsv($feedHandle, 0, ',')) !== false) {
    $row = array_combine($feedHeader, $feedRow);
    $skuStockMap[$row['sku']] = $row['stock']; // sku直接当数组键
}
fclose($feedHandle);

// 第二步:逐行处理主库存,写入新文件
$inventoryHandle = fopen('Inventory.csv', 'r');
$newInventoryHandle = fopen('updatedStockInventory.csv', 'w');
$rowIndex = 0;
while ($inventoryRow = fgetcsv($inventoryHandle, 0, '|')) {
    $rowIndex++;
    // 保留表头直接写入
    if ($rowIndex === 1) {
        fputcsv($newInventoryHandle, $inventoryRow, '|');
        continue;
    }
    $currentSku = $inventoryRow[2]; // 你代码里sku在第3列(索引2)
    // 直接通过索引查库存,没有匹配就保留原库存
    if (isset($skuStockMap[$currentSku])) {
        $inventoryRow[3] = $skuStockMap[$currentSku]; // 假设库存字段在第4列(索引3),根据实际调整
    }
    fputcsv($newInventoryHandle, $inventoryRow, '|');
}
fclose($inventoryHandle);
fclose($newInventoryHandle);
?>

额外优化说明:

  • 避免使用file()函数一次性加载整个CSV到内存,改用fgetcsv逐行读取,内存占用可以稳定在10MB以内,不受文件大小影响
  • 直接用fputcsv生成新行,避免手动拼接字符串出错
其他高效处理方案

如果后续数据量继续增长,可以选择更适合的工具:

  • 纯同步无复杂业务逻辑的场景,可以直接用awk命令行工具处理,处理百万行CSV的速度比PHP快30%~50%
  • 有复杂关联逻辑的场景,可以将两个CSV导入MySQL临时表,通过UPDATE JOIN语句批量更新后再导出,千万级数据处理效率远高于脚本逐行处理
  • 高频更新场景建议抛弃CSV存储,改用Redis或者MySQL存储库存数据,直接按sku更新对应值,避免每次全量扫描文件,性能可以提升几个数量级

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:06:04