Sobes.tech
Middle

Čo je problém n+1 vzorky?

sobes.tech AI

Odpoveď od AI

Toto je problém výkonu pri práci s databázami, keď je na získanie súvisiacich údajov potrebných N+1 dotazov namiesto jedného.

Vyskytuje sa, keď:

  1. Je vykonaný jeden dotaz na získanie zoznamu hlavných entít.
  2. Potom pre každú z týchto entít je vykonaný samostatný dotaz na získanie súvisiacich podriadených entít.

Príklad v JPA:

// Získanie zoznamu používateľov
List<User> users = userRepository.findAll();

// Pre každého používateľa získať jeho objednávky
for (User user : users) {
    List<Order> orders = user.getOrders(); // Vyvolá N dotazov do DB, jeden pre každého používateľa
}

Riešenie: Použiť dotazy s načítaním súvisiacich údajov naraz:

  1. JOIN FETCH: Načítanie súvisiacich entít spolu s hlavnou v jednom dotaze.

    // Príklad s JPQL
    List<User> users = entityManager.createQuery("SELECT u FROM User u JOIN FETCH u.orders", User.class).getResultList();
    
  2. EntityGraph: Deklarovanie grafu entít na určenie, ktoré súvisiace objekty majú byť načítané.

    // Na úrovni entity
    @Entity
    @NamedEntityGraph(name = "User.orders", attributeNodes = @NamedAttributeNode("orders"))
    public class User {
        // ...
    }
    
    // Použitie v repozitári
    @Query("SELECT u FROM User u")
    @EntityGraph(value = "User.orders")
    List<User> findAllWithOrders();
    
  3. Batch Fetching: Načítanie súvisiacich objektov vo skupinách (ORM to môže robiť na pozadí s vhodnou konfiguráciou).

Riešenie problému N+1 výrazne zlepšuje výkon aplikácií, znižuje počet volaní na databázu.