Как посеять большие наборы данных быстрее в laravel, используя фейкер
Я помещаю 25000 записей в 1 таблицу, используя фабрики фейерверков и моделей Laravel, и на это уходит около 30 минут, а это только снижает мою производительность. Есть ли способ посеять такие большие наборы данных в гораздо меньшее время. как минута
Это модельная фабрика
<?php
use App\Models\Client\Client;
use Faker\Generator;
$factory->define(Client::class, function (Generator $faker) {
$employeecount = [15,48,5,12,26,30];
$numbers = [0125554,0145755,0123456,8874545,4512156];
$gross = [25000,13500,10000,8500,5000,15000,30000];
$gender = ['Male','Female'];
$marketing = ['E-mail','SMS','Telephone'];
$maritalstatus = ['Single','Married','Divorced','Widow'];
$maritaltype = ['COP','ANC'];
$addresstype = ['Owner','Rent'];
$serviceused = ['Status Insight','Credit Union'];
$riskstatus = ['Low Risk','Medium Risk','High Risk'];
$companytype = ['Public Company','CC','Partnership','Sole Trader','PTY','TLD','Other'];
return [
'name' =>$faker->firstName,
'surname' =>$faker->lastName,
'idnumber' =>$faker->unique()->ean8,
'gender' =>$gender[array_rand($gender)],
'maritalstatus' =>$maritalstatus[array_rand($maritalstatus)],
'maritaltype' =>$maritaltype[array_rand($maritaltype)],
'maidenname' =>$faker->lastName,
'companytype' =>$companytype[array_rand($companytype)],
'companyname' =>$faker->company,
'businessnature' =>$faker->catchPhrase,
'vatnumber' =>$numbers[array_rand($numbers)],
'coregnumber' =>$numbers[array_rand($numbers)],
'tradingname' =>$faker->bs,
'employeecount' =>$employeecount[array_rand($employeecount)],
'employer' =>$faker->company,
'gross' =>$gross[array_rand($gross)],
'mobilenumber' =>$numbers[array_rand($numbers)],
'homenumber' =>$numbers[array_rand($numbers)],
'worknumber' =>$numbers[array_rand($numbers)],
'email' =>$faker->email,
'marketing' =>$marketing[array_rand($marketing)],
'physicaladd1' =>$faker->streetAddress,
'physicaladd2' =>$faker->streetName,
'physicalcity' =>$faker->city,
'physicalcode' =>str_pad(rand(0, pow(10, 4) - 1), 4, '0', STR_PAD_LEFT),
'yearsAtAddress' =>str_pad(rand(0, pow(4, 2) - 1), 2),
'monthsAtAddress' =>str_pad(rand(0, pow(4, 2) - 1), 2),
'addresstype' =>$addresstype[array_rand($addresstype)],
'postaladd1' =>$faker->streetAddress,
'postaladd2' =>$faker->streetName,
'postalcity' =>$faker->city,
'postalcode' =>str_pad(rand(0, pow(10, 4) - 1), 4, '0', STR_PAD_LEFT),
'riskstatus' =>$riskstatus[array_rand($riskstatus)],
'noofjudgements' =>str_pad(rand(0, pow(2, 2) - 1), 2),
'noofdefaults' =>str_pad(rand(0, pow(2, 2) - 1), 2),
'dateofenquiry' =>$faker->date($format = 'Y-m-d', $max = 'now'),
'serviceused' =>$serviceused[array_rand($serviceused)],
];
});
Это столовая сеялка
<?php
use App\Models\Client\Client;
use Illuminate\Database\Seeder;
class ClientTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
factory(Client::class, 25000)->create();
}
}
И это главный сеялка
<?php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Seeder;
/**
* Class DatabaseSeeder.
*/
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Model::unguard();
$this->call(ClientTableSeeder::class);
Model::reguard();
}
}
Кто-нибудь с лучшим решением? Заранее спасибо.
3 ответа
По моему многолетнему опыту, фабрики в этом случае не подходят.
Решение, которое я нашел, работает быстрее, чем Factory, — это Seeder.
Что я делаю, так это создаю огромную коллекцию данных, например, 25000~50000 записей.
Затем используйте Collection::chunk для вставки (не создания) множества (500 ~ 1000+) записей одновременно.
В конечном итоге сокращается количество запросов, таким образом, время.
например
$collectionToInsert = collect([]);
$numberOfEntries = 25000;
for ($i = 1; $i <= $numberOfEntries; $i++) {
$collectionToInsert->push([
'name' => $faker->firstName,
'surname' => $faker->lastName,
'idnumber' => $faker->unique()->ean8,
// ...
]);
}
$chunks = $collectionToInsert->chunk(500);
foreach ($chunks as $chunk) {
SomeModel::insert($chunk->toArray());
}
для больших данных у нас есть 2 решения:1-: создать файл csv и использовать команду MYSQL «ЗАГРУЗИТЬ В ФАЙЛ».https://www.mockaroo.com/ может помочь создать поддельный csv
2- я использовал
for($i=0 ; $i< 6000 ; $i++){
$records = AhrefRecord::factory()->count(1000)->make();
$chunks = $records->chunk(500);
foreach ($chunks as $chunk) {
AhrefRecord::insert($chunk->toArray());
}
}
за создание 60-метровых записей и ускорение вставки в 10 раз. Просто выберите кусок, и «для оператора» зависит от вашего php.ini memory_limit.
уведомление: для вставки отношения я обрабатывал вручную: у меня было отношение между ahref_table и ahref_records_table, сначала я вставляю 800 записей в ahref_table, затем я вставляю 60 миллионов записей для второй таблицы (ahref_records_table) со случайным внешним идентификатором от 1 до 800
Попробуйте и используйте это. Это поможет
композитор требует fzaninotto/faker --dev