如何在Laravel上插入大数据?

时间:2018-07-23 22:02:05

标签: laravel laravel-5 insert bigdata laravel-5.6

我正在使用laravel 5.6

我插入大数据的脚本是这样的:

...
$insert_data = [];
foreach ($json['value'] as $value) {
    $posting_date = Carbon::parse($value['Posting_Date']);
    $posting_date = $posting_date->format('Y-m-d');
    $data = [
        'item_no'                   => $value['Item_No'],
        'entry_no'                  => $value['Entry_No'], 
        'document_no'               => $value['Document_No'],
        'posting_date'              => $posting_date,
        ....
    ];
    $insert_data[] = $data;
}
\DB::table('items_details')->insert($insert_data);

我试图用脚本插入100条记录,它可以工作。成功插入数据

但是,如果我尝试在脚本中插入50000条记录,它将变得非常缓慢。我已经等了大约10分钟,但没有成功。存在这样的错误:

504 Gateway Time-out

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:3)

如前所述,如果这是时间执行问题,那么在这种情况下,块实际上并不能帮助您。我认为您尝试使用的批量插入无法处理该数量的数据,因此我看到2个选项:

1-重新组织代码以正确使用块,这看起来像这样:

$insert_data = [];

foreach ($json['value'] as $value) {
    $posting_date = Carbon::parse($value['Posting_Date']);

    $posting_date = $posting_date->format('Y-m-d');

    $data = [
        'item_no'                   => $value['Item_No'],
        'entry_no'                  => $value['Entry_No'], 
        'document_no'               => $value['Document_No'],
        'posting_date'              => $posting_date,
        ....
    ];

    $insert_data[] = $data;
}

$insert_data = collect($insert_data); // Make a collection to use the chunk method

// it will chunk the dataset in smaller collections containing 500 values each. 
// Play with the value to get best result
$chunks = $insert_data->chunk(500);

foreach ($chunks as $chunk)
{
   \DB::table('items_details')->insert($chunk->toArray());
}

这样,您的批量插入内容将包含较少的数据,并且能够以相当快的方式进行处理。

2-如果主机支持运行时重载,则可以在代码开始执行之前添加一条指令:

ini_set('max_execution_time', 120 ) ; // time in seconds

$insert_data = [];

foreach ($json['value'] as $value)
{
   ...
}

要了解更多信息,请访问官方docs

答案 1 :(得分:0)

使用数组然后将其转换为集合没有任何意义。

我们可以摆脱数组。

$insert_data = collect();

foreach ($json['value'] as $value) {
    $posting_date = Carbon::parse($value['Posting_Date']);

    $posting_date = $posting_date->format('Y-m-d');

    $insert_data->push([
        'item_no'                   => $value['Item_No'],
        'entry_no'                  => $value['Entry_No'], 
        'document_no'               => $value['Document_No'],
        'posting_date'              => $posting_date,
        ....
    ]);
}

foreach ($insert_data->chunk(500) as $chunk)
{
   \DB::table('items_details')->insert($chunk->toArray());
}

答案 2 :(得分:0)

这是一个非常好的而且非常快速的插入数据解决方案

$no_of_data = 1000000;
$test_data = array();
for ($i = 0; $i < $no_of_data; $i++){
    $test_data[$i]['number'] = "1234567890";
    $test_data[$i]['message'] = "Test Data";
    $test_data[$i]['status'] = "Delivered";
}
$chunk_data = array_chunk($test_data, 1000);
if (isset($chunk_data) && !empty($chunk_data)) {
   foreach ($chunk_data as $chunk_data_val) {
    DB::table('messages')->insert($chunk_data_val);
  }
}

答案 3 :(得分:0)

我用下面的代码检查了11000行的更新或插入数据。希望对你有用。

$insert_data = [];
for ($i=0; $i < 11000; $i++) { 
    $data = [
        'id' =>'user_'.$i,
        'fullname' => 'Pixs Nguyen',
        'username' => 'abc@gmail.com',
        'timestamp' => '2020-03-23 08:12:00',
    ];
    $insert_data[] = $data;
}

$insert_data = collect($insert_data); // Make a collection to use the chunk method

// it will chunk the dataset in smaller collections containing 500 values each. 
// Play with the value to get best result
$accounts = $insert_data->chunk(500);
// In the case of updating or inserting you will take about 35 seconds to execute the code below
for ($i=0; $i < count($accounts); $i++) { 
    foreach ($accounts[$i] as $key => $account)
    {
        DB::table('yourTable')->updateOrInsert(['id'=>$account['id']],$account);
    }
}
// In the case of inserting you only take about 0.35 seconds to execute the code below
foreach ($accounts as $key => $account)
{
    DB::table('yourTable')->insert($account->toArray());
}