I have a Model called CommunityProfile. This model contains two child relationships; player (type User), and rank (type Rank).
The default spring boot JPA-generated query is taking approximately 9s to fetch 200 records, which is rather slow. By using the following MySQL query, I can return the data I need rather quickly:
SELECT cp.*, r.*, u.* FROM community_profiles cp
LEFT JOIN users u ON cp.player_id = u.id
LEFT JOIN ranks r ON cp.rank_id = r.id
WHERE cp.community_id = 1
How can I make my repository map the results to their correct Objects/Models?
I have tried using a non-native query, like this:
@Query("SELECT cp FROM CommunityProfile cp " +
"LEFT JOIN FETCH cp.player u " +
"LEFT JOIN FETCH cp.rank r " +
"WHERE cp.communityId = :communityId")
List<CommunityProfile> findByCommunityIdWithJoin(@Param("communityId") Integer communityId);
However, this is still quite slow in comparison, resulting in an 800-900ms response. For comparison, my current Laravel application can return the same data in a 400-ms cold start.
Any tips are appreciated, thank you
==UPDATE==
After trying the suggested @Index annotation, I still don’t really see any performance gains. Did I implement correctly?
@Entity
@Table(name = "community_profiles", indexes = @Index(name = "cp_ci_idx", columnList = "community_id"))
public class CommunityProfile {
2
Answers
If your JPA query is working, and you are just asking about performance, you may add the following index:
This index should allow MySQL to filter off records which are not part of the result set.
From JPA itself you may use:
Have you tried EntityManager
Once I used this kind of native query inside loop and it constantly returned cash values bu entityManagaer.clear() clears cash. This is for info only)
Or create an Index on specific columns when you are defining entity classes like:
For Non-entity @Index you can check documentation