This sounds like the kind of operations that a relational
database is intended for.
I would suggest using DBI together with
DBD::CSV if you want to keep on using flatfiles.
And then when you get tired of bad performance you can
just use a real database instead. :-)