Sobes.tech
Middle
191

Τι είναι το πρόβλημα δείγματος n+1;

Απάντηση από AI

sobes.tech AI

Αυτό είναι ένα πρόβλημα απόδοσης κατά την εργασία με βάσεις δεδομένων, όπου απαιτούνται N+1 ερωτήματα αντί για ένα μόνο για την απόκτηση σχετικών δεδομένων.

Προκύπτει όταν:

  1. Εκτελείται ένα ερώτημα για την απόκτηση της λίστας των κύριων οντοτήτων.
  2. Στη συνέχεια, για κάθε μία από αυτές τις οντότητες, εκτελείται ένα ξεχωριστό ερώτημα για την απόκτηση των σχετικών παιδικών οντοτήτων.

Παράδειγμα σε JPA:

// Λήψη της λίστας χρηστών
List<User> users = userRepository.findAll();

// Για κάθε χρήστη, λήψη των παραγγελιών του
for (User user : users) {
    List<Order> orders = user.getOrders(); // Καλεί N ερωτήματα στη βάση δεδομένων, ένα για κάθε χρήστη
}

Λύση: Χρησιμοποιήστε ερωτήματα με φόρτωση σχετικών δεδομένων σε μία μόνο λειτουργία:

  1. JOIN FETCH: Φόρτωση των σχετικών οντοτήτων μαζί με την κύρια σε ένα ερώτημα.

    // Παράδειγμα με JPQL
    List<User> users = entityManager.createQuery("SELECT u FROM User u JOIN FETCH u.orders", User.class).getResultList();
    
  2. EntityGraph: Δήλωση ενός γραφήματος οντοτήτων για να υποδείξετε ποια σχετιζόμενα αντικείμενα πρέπει να φορτωθούν.

    // Σε επίπεδο οντότητας
    @Entity
    @NamedEntityGraph(name = "User.orders", attributeNodes = @NamedAttributeNode("orders"))
    public class User {
        // ...
    }
    
    // Χρήση στο αποθετήριο
    @Query("SELECT u FROM User u")
    @EntityGraph(value = "User.orders")
    List<User> findAllWithOrders();
    
  3. Batch Fetching: Φόρτωση σχετικών αντικειμένων σε παρτίδες (το ORM μπορεί να το κάνει στο παρασκήνιο με κατάλληλη διαμόρφωση).

Η επίλυση του προβλήματος N+1 βελτιώνει σημαντικά την απόδοση των εφαρμογών, μειώνοντας τον αριθμό των κλήσεων στη βάση δεδομένων.