Well this is a very open question it depends on your Report Definition. If you are not reporting on BLOB values it is already a good point. Can you share the configuration of your report or shared few database numbers.
The first step is to make sure all of the properties you are retrieving or using for join conditions are exposed.
The next is to obtain an explain plan for the query that is being executed for the report, and tune the database accordingly. This primarily means adding indexes to the appropriate columns to maximize the efficiency of the retrieval. If you have resident database experts they can analyze the explain plan and make recommendations about indexes to add.
These are usually enough to do the trick. If you have a unique situation where they are insufficient, then it's possible more sophisticated techniques can be applied.
If exposing columns is not enough to do the trick, you need to look at a larger picture. For instance:
1) Is the report generating a very complex query? If so, why? E.g., are you trying to support too many usage scenarios with just one report? Splitting the report into smaller more specialized reports will reduce the complexity.
2) Are you re-executing queries and joins to static data every time you run the report? You might be better off pre-populating a table or view with join and sub-query data and just joining to that during the main report execution.
3) If you are doing joins, make sure the join columns are indexed. Joins on unindexed columns can kill the performance of a report.
It is also worth to check From Pega Alert, you can check Pega0005 and Pega0042 for this query to identify whether you have both issues (join and fetching). This alert should be fixed by creating required indexes on the table mapped.