如何在laravel上插入大数据?
How to insert big data on the laravel?
我正在使用 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
我该如何解决这个问题?
如前所述,如果是时间执行问题,块在这种情况下不会真正帮助您。我认为您尝试使用的批量插入无法处理那么多数据,所以我看到了 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
使用数组然后将其转换为集合是没有意义的。
我们可以去掉数组。
$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());
}
这里有很好很快速的插入数据解决方案
$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);
}
}
我使用下面的代码检查了 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());
}
我正在使用 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
我该如何解决这个问题?
如前所述,如果是时间执行问题,块在这种情况下不会真正帮助您。我认为您尝试使用的批量插入无法处理那么多数据,所以我看到了 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
使用数组然后将其转换为集合是没有意义的。
我们可以去掉数组。
$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());
}
这里有很好很快速的插入数据解决方案
$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);
}
}
我使用下面的代码检查了 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());
}