2010-05-20 4 views
1

Comment les utilisateurs récupèrent-ils tous les objets dans le code dès le départ?Récupérer tous les objets dans le code dès le départ pour des raisons de performances

Je pense que vous pouvez augmenter les performances si vous regroupez tous les appels de modèle ensemble?

Cela fait pour une plus grande affaire, surtout si votre DB ne peut pas tout garder en mémoire

def hitDBSeperately {

get utilisateurs X ... Code

obtenir les utilisateurs Y .. . Code

obtenir les utilisateurs Z ... Code

}

Versus:

def hitDBInSingleCall {

get X + Y + Z utilisateurs

code pour le code X Y ...

}

Répondre

1

Vous cherchez une explication entre l'approche dans laquelle vous chargez dans tous les utilisateurs à la fois:

# Loads all users into memory simultaneously 
@users = User.all 

@users.each do |user| 
    # ... 
end 

Où vous pouvez les charger individuellement pour une plus petite empreinte mémoire?

@user_ids = User.connection.select_values("SELECT id FROM users") 

@user_ids.each do |user_id| 
    user = User.find(user_id) 

    # ... 
end 

La deuxième approche serait plus lente car elle nécessite N + 1 requêtes pour les utilisateurs N, où les premières charges tous avec 1 requête. Toutefois, vous devez disposer de suffisamment de mémoire pour créer des instances de modèle pour chaque enregistrement utilisateur en même temps. Ce n'est pas une fonction de "mémoire DB", mais de la mémoire de l'application.

Pour toute application avec un nombre non négligeable d'utilisateurs, vous devez utiliser une approche où vous chargez les utilisateurs individuellement ou en groupes. Vous pouvez le faire en utilisant:

@user_ids.in_groups_of(10) do |user_ids| 
    User.find_all_by_id(user_ids).each do |user| 
    # ... 
    end 
end 

En réglant pour utiliser un facteur de regroupement approprié, vous pouvez équilibrer l'utilisation de la mémoire et les performances.

Questions connexes