Optimizing query performance with aggregation tables and partitioning
I would recommend trying a single-table design.  There would be groups of columns which are only relevant to a single type, meaning they would be NULL for rows of any of the other types.  For the physical layout of the table, you would probably want the common columns first, then the frequently filtered-upon type-specific columns, then the infrequently/never filtered-upon type-specific columns last.

This will get rid of the problem of needing to do left joins.  It will also make it easy to partition on timestamps, as you no longer have the side tables which lack timestamps.  Hopefully the large text fields will get TOASTed aggressively, keeping the size of the main table down (but this is not something easy to control).

If the partitions with the most recent timestamps are the hottest ones, this will help keep their data and their indexes small enough to fit RAM cache, and hot enough to be naturally kept there.