I'm importing a big dataset of medication usage (14 years of public health system data from Brazil) for a data science project.
When I first started, I created one of the tables with all the indexes (one int4, one int8, one bpchar(2) and one bpchar(4)), but this caused the COPY transactions to become very slow, so I dropped the indexes to speed up data ingestion.
It worked, and I finished importing the 655GB (roughly 2.5 billion rows) last week. However, when trying to create the indexes, the code ran for three days straight and never finished, and I ended up losing the progress for the indexes. I'm working on getting an UPS for this.
I tried creating all indexes at the same time, in parallel, to finish as soon as possible, but I believe the concurrency between different indexes ended up creating an IO bottleneck (using 100% of my HDDs IO capacity this whole time).
I have followed some tips I found in this link to try and speed up creation, as follows:
- I've set the table parallel_workers setting to 6, as well as pg variable max_parallel_maintenance_workers to 6.
- I have set the pg variable maintenance_work_mem to 1.5GB. For some reason my instance only lets me raise it to just below 2GB, and I haven't found out how to increase this limit yet.
- I haven't experimented with checkpoint_timeout, max_wal_size or min_wal_size, because I didn't really understand what they mean, so I decided to leave them alone for now.
I'm running this in my personal computer: 32gb RAM, Ryzen 5, a dedicated 4TB HDD for the database. On Windows 10 Home. I have the intention of acquiring one or two additional SSD to house the database, since IO has been such a bottleneck.
I believe I should probably stick to one index at a time, focusing all resources to its creation, but I am not sure, and I don't want to waste another week just to find out. This is the first time I'm creating and managing a database by myself, and most things I know are from stackexchange and postgresql.org/docs.
Was I right to drop the indexes before COPY?
How should I approach the creation of the indexes, what postgresql settings should I customize (and how) to do it as fast as possible?
And lastly, should I get two SSDs for partitions? Or an SSD for the data and the existing HDD for the WAL would be enough? Or something different? I really don't know how to deal with this, and would prefer to know more before buying more hardware.