Seed Millions Of Records To Local Database With Laravel
Mar 24, 2022When you are working on some big project, you will probably need to test speed of your queries, and for that you will need to have a lot of fake records in your database.
You can do this with database seeders, but it can be really slow if you need to seed couple millions of records to database.
In this article I will show you better and faster way for doing this.
Setup Project
Let's first setup our project. It will be a really basic app with one table and one column.
Create fresh Laravel project, at the time of writing this article latest version of Laravel framework is 9.5.1.
Create a model "Data" with migration, factory and seeder.
In migration file add new field "code" which will be string.
Run migrations.
As last step, let's create a factory to insert 10 random characters for "code" field.
That's it. We have now our project ready.
Seed Database
For this case, our goal will be to seed 10 million records to our table "data".
We will first seed 1.000 records to see how much time it takes and based on that we will calculate how much time it would take to seed 10 million records.
Let's define it in the DataSeeder class. We will call factory method on our model and pass to it number of records we want to seed.
And we will call our seeder class in the DatabaseSeeder class.
Let's run our seeder and see how long it take to seed 1.000 records to database.
As we can see, it took ~10s to seed 1.000 records to database. So if we calculate how much time it would take this approach to seed 10 million records it will be:
So, to seed 10 million records to database with this approach will take us ~28 hour.
Let's try another approach. We will first create array with data we want to insert to database. After that, we will split that array into chunks and for each of those chunks we will call "insert" method on our model.
Make changes in our DataSeeder class.
$chunks = array_chunk($data, 500);
foreach ($chunks as $chunk) { \App\Models\Data::insert($chunk); } }
Let's run again our seeder to see how much time it takes with this approach to seed 1.000 records to database.
As you can see, now it takes ~71ms to seed 1.000 records to database.
If we calculate how much time it will take to seed 10 million records, we get:
It will take around ~12 minutes to seed same amount of data.
But this can be even faster if we get bigger chunks of data. Let's try to seed 100.000 records with chunks of 50.000.
If we calculate how much time it will take to seed 10 million records, we get:
So, if we compare these results, we see that for 10 million records in a standard way of seeding it will take ~28 hours and in this way ~3 minutes.
Conclusion
Of course, I do not suggesting to seed 10 million at once, separate it in a couple of runs (maybe 1 million per run?) and you will probably need to play a little with number of chunks to see what works fastest.
That's it. You can now seed your database with a million of records in a couple of minutes.