Use the database's native bulk-load path (Postgres COPY, MySQL ), split the file into chunks loaded into a with indexes and constraints , then rebuild indexes once and merge — and make the whole job so a crash can resume without duplicating rows.
