An import loop calling wp_insert_post() is doing everything a human clicking Publish does: revisions, term counting, ping status, and every plugin listening on save_post. For ten posts that is invisible; for fifty thousand it is the whole night.
wp_defer_term_counting( true );
wp_defer_comment_counting( true );
remove_action( 'save_post', 'my_expensive_reindex' );
foreach ( $rows as $row ) {
wp_insert_post( $row );
}
wp_defer_term_counting( false ); // recounts once, here
wp_defer_comment_counting( false );
Deferring term counting is the largest single win, because otherwise every insert recounts every term it touches. Removing your own hooks and running the work once at the end is the next. What you must not do is write to wp_posts directly to avoid all this — the caches, the meta and the term relationships will not match, and the failure surfaces much later.