Middle
Mi az n+1 mintavételi probléma?
sobes.tech MI
Válasz az MI-től
Ez egy teljesítményprobléma adatbázisokkal való munkavégzés közben, amikor a kapcsolódó adatok lekéréséhez N+1 lekérdezés szükséges egy helyett.
Ez akkor fordul elő, amikor:
- Egy lekérdezést hajtanak végre a fő entitások listájának megszerzéséhez.
- Ezután minden egyes entitáshoz külön lekérdezést hajtanak végre a kapcsolódó gyermek entitások megszerzéséhez.
Példa JPA-ban:
// Felhasználók listájának lekérése
List<User> users = userRepository.findAll();
// Minden felhasználóhoz kérjük le a rendeléseit
for (User user : users) {
List<Order> orders = user.getOrders(); // N lekérdezést hív meg az adatbázisban, egyet minden felhasználóhoz
}
Megoldás: Használjon olyan lekérdezéseket, amelyek egy lépésben betöltik a kapcsolódó adatokat:
-
JOIN FETCH: A kapcsolódó entitások betöltése a fő entitással együtt egy lekérdezésben.
// JPQL példával List<User> users = entityManager.createQuery("SELECT u FROM User u JOIN FETCH u.orders", User.class).getResultList(); -
EntityGraph: Egy entitás gráfjának deklarálása, hogy megadja, mely kapcsolódó objektumokat kell betölteni.
// Entitás szinten @Entity @NamedEntityGraph(name = "User.orders", attributeNodes = @NamedAttributeNode("orders")) public class User { // ... } // A repository-ban való használat @Query("SELECT u FROM User u") @EntityGraph(value = "User.orders") List<User> findAllWithOrders(); -
Batch Fetching: A kapcsolódó objektumok csoportos betöltése (az ORM ezt háttérben, megfelelő konfigurációval megteheti).
A N+1 problémának a megoldása jelentősen javítja az alkalmazások teljesítményét, csökkentve az adatbázis-kérések számát.