Refactor to split up query for performance

The prior implementation would build one query joining everything
together that was involved. This version will first get the primary
entity IDs, cache those in the DB, then issue a query for each entity
group that is involved. Much fatser.