Résoudre le problème de requête N 1 dans JPA et Hibernate
Le problème N 1 survient lorsqu'une requête récupère N enregistrements et que les requêtes suivantes récupèrent des éléments associés enregistrements, conduisant à N requêtes supplémentaires. Cela peut se produire dans Hibernate lorsqu'une association n'est pas récupérée lors de la requête initiale.
Cause et effet
Pour illustrer, considérons cette requête JPA qui récupère les entités PostComment :
List<PostComment> comments = entityManager.createQuery("select pc from PostComment pc where pc.review = :review", PostComment.class) .setParameter("review", review) .getResultList();
Si nous parcourons ensuite les commentaires et accédons à l'association de publication, Hibernate émettra les instructions SQL suivantes :
SELECT pc.id AS id1_1_, pc.post_id AS post_id3_1_, pc.review AS review2_1_ FROM post_comment pc WHERE pc.review = 'Excellent!' INFO - Loaded 3 comments SELECT pc.id AS id1_0_0_, pc.title AS title2_0_0_ FROM post pc WHERE pc.id = 1 INFO - The post title is 'Post nr. 1' SELECT pc.id AS id1_0_0_, pc.title AS title2_0_0_ FROM post pc WHERE pc.id = 2 INFO - The post title is 'Post nr. 2' SELECT pc.id AS id1_0_0_, pc.title AS title2_0_0_ FROM post pc WHERE pc.id = 3 INFO - The post title is 'Post nr. 3'
Ici, trois requêtes supplémentaires sont exécutées pour récupérer les entités Post. pour chaque commentaire. Il s'agit du problème de requête N 1.
Résolution
Pour résoudre ce problème, nous pouvons récupérer avec impatience les associations requises à l'aide du mot-clé JOIN FETCH :
List<PostComment> comments = entityManager.createQuery("select pc from PostComment pc join fetch pc.post p where pc.review = :review", PostComment.class) .setParameter("review", review) .getResultList();
Pour plusieurs associations d'enfants, il est recommandé de récupérer une collection dans la requête initiale et de charger le reste via des requêtes secondaires.
Détection automatisée
Pour détecter le N 1, il est avantageux d'implémenter des tests d'intégration avec la journalisation et les assertions SQL pour vérifier le nombre attendu d'instructions SQL générées. Des outils comme db-util peuvent vous aider dans ce processus.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!