[eluser]jonez[/eluser]
What I mean by conditional logic is when your are working with a DB, make it do the least amount of work possible. In your case, you have a function that inserts a base record then attempts to add child rows for that record. Instead of checking if child data exists (and thus the base record is needed), you insert first, then later on you see you don't have child records and you shouldn't have inserted the base so you remove it with a rollback. This is much less efficient than checking if child rows exist before doing anything else, if not skip the entire function otherwise insert the base and add the children. Think of it as preparing the data before actually inserting it, discarding anything that isn't needed. Then use transactions to catch errors in the data (missing or invalid fields) and enforce foreign key constraints.
A good chunk of your DB commands could be avoided with data checks. PHP conditionals are considerably faster than doing insert/rollbacks. Prepare the data, use insert_batch instead of for loops for children, and you should be able to reduce the execution time significantly. 3mins for anything other than bulk data migration is too much.
As an example I recently wrote a data migration script for our system (MySQL). I had to move account data (users, files, documents, etc) from one system to another. In total it was 2058 records that were spread relationally across ~20 tables. What I did was collect everything in a series of arrays, then used transactions and bulk inserts to insert everything into the new system. Including copying their physical files (only paths are stored in DB) it took less than 30 seconds to run.