laravel 批量插入和in查询速度很慢怎么解决

1. 批量插入,大于2000条一次的时候,laravel处理就花了5s以上,排查应该是在Arr::flatten这里压缩数据,merge花了极大的时间。

2.whereIn 数量很大的时候同上。


分批插拆的太小速度也不行,这种除了自己写原生sql还有什么好的解决方案吗

9 条回复

  1. sundong_wyz sundong_wyz says:
    @ 学院君
    /**
     * @param int $number 插入总数
     * @param int $width 子项个数
     * @param int $type 类型 1.laravel 2.普通
     */
    function test($number = 0, $width = 10, $type = 1) 
    {
    
        // 组装一个大点儿栋二维数组,模拟批量插入
        $item = range(1, $width);
    
        $array = [];
    
        while ($number) {
            $array[] = $item;
            $number--;
        }
    
        echo "模拟插入: " . count($array) . " 条数据\n";
    
        $merge = [];
        $start = microtime(true);
    
        // Laravel里面栋faltten压缩二维数组压缩为一维数组
        if ($type == 1) {
            $merge = array_reduce($array, function($res, $value) {
                return array_merge($res, array_values($value));
            }, []);
        } else {
            // 自己直接遍历,实现二维数组压缩为一维数组
            foreach ($array as $key => $value) {
                foreach ($value as $k => $v) {
                    $merge[] = $v;
                }
            }
        }
    
        echo "组装耗时: " . (microtime(true) - $start) . "\n绑定总数: " . count($merge). "\n\n";
    }
    
    $test = range(1, 10);
    
    foreach ($test as $key => $value) {
        echo "------------------------------------\n";
        test($value * 1000, 10, 1);
        test($value * 1000, 10, 2);
    }
  2. sundong_wyz sundong_wyz says:
    @ 学院君

    这是个小模拟:

    $array = []; while ($number) { $array[] = $item; $number--; }

    echo "模拟插入: " . count($array) . " 条数据\n";

    $merge = []; $start = microtime(true);

    // Laravel里面栋faltten压缩二维数组压缩为一维数组 $merge = array_reduce($array, function($res, $value) { return array_merge($res, array_values($value)); }, []);

    // 自己直接遍历,实现二维数组压缩为一维数组 // foreach ($array as $key => $value) { // foreach ($value as $k => $v) { // $merge[] = $v; // } // }

    echo "组装耗时: " . (microtime(true) - $start) . "\n绑定总数: " . count($merge). "\n";

  3. sundong_wyz sundong_wyz says:
    @ 学院君

    这个总感觉不太科学,即使我这些是在脚本任务里面,本来原生几秒可执行完的,框架给执行了几分钟。性能损失过于严重。

  4. sundong_wyz sundong_wyz says:
    @ 学院君

    系统数据量比较大,有些场景的确需要这个。递归用这个array_merge真的好慢,感觉改了这个就会快很多。只能领出来单独封装一下了

  5. 学院君 学院君 says:

    这个就是这样 所以只能通过编码去约束 in 查询一次不要超过 2000 条 批量插入通过一条 insert 语句实现要好点 日常场景下也没有一次要插2000条的吧 多半是脚本任务才有这种需求

登录后才能进行评论,立即登录?