Dans Rails, vous pouvez trouver le nombre d'enregistrements en utilisant à la fois Model.size
et Model.count
. Si vous traitez des requêtes plus complexes, y a-t-il un avantage à utiliser une méthode par rapport à l'autre? Comment sont-ils différents?
Par exemple, j'ai des utilisateurs avec des photos. Si je veux montrer un tableau des utilisateurs et combien de photos ils ont, l'exécution de nombreuses instances user.photos.size
sera-t-elle plus rapide ou plus lente que user.photos.count
?
Merci!
size
de toute façon, la situation s’adapte à la situation, alors à quoi bonlength
etcount
à quoi bon ?size
peut donc les appeler lorsque vous effectuez l'appelsize
(après avoir déterminé lequel appeler).Comment.create(post_id: post.id)
-à- dire , votrepost.comments.size
volonté ne sera pas à jour, alors que lepost.comments.count
sera. Soyez donc prudent.company.devices.build(:name => "device1"); company.devices.build(:name => "device2")
alorscompany.devices.size
et.length
inclura le nombre d'objets que vous avez construits mais que vous n'avez pas enregistrés,.count
ne rapportera que le nombre de la base de données.Comme les autres réponses le disent:
count
exécutera uneCOUNT
requête SQLlength
va calculer la longueur du tableau résultantsize
va essayer de choisir le plus approprié des deux pour éviter des requêtes excessivesMais il y a encore une chose. Nous avons remarqué un cas où
size
agit différemment decount
/length
tout à fait, et j'ai pensé le partager car il est assez rare pour être ignoré.Si vous utilisez un
:counter_cache
sur unehas_many
association,size
utilisera directement le nombre mis en cache et ne fera aucune requête supplémentaire.Ce comportement est documenté dans les guides Rails , mais soit je l'ai raté la première fois, soit je l'ai oublié.
la source
_count
colonne (sans lacounter_cache: true
directive sur l'association). Ce problèmeParfois,
size
"choisit le mauvais" et renvoie un hachage (ce quicount
ferait l'affaire)Dans ce cas, utilisez
length
pour obtenir un entier au lieu du hachage .la source
tl; dr
count
.length
.size
...compter
Décide d'envoyer une
Select count(*)...
requête à la base de données. La voie à suivre si vous n'avez pas besoin des données, mais simplement du nombre.Exemple: nombre de nouveaux messages, nombre total d'éléments lorsque seule une page va être affichée, etc.
longueur
Charge les données requises, c'est-à-dire la requête comme requis, puis les compte simplement. La voie à suivre si vous utilisez les données.
Exemple: résumé d'un tableau entièrement chargé, titres des données affichées, etc.
Taille
Il vérifie si les données ont été chargées (c'est-à-dire déjà dans des rails) si c'est le cas, puis il suffit de les compter, sinon il appelle count. (plus les pièges, déjà mentionnés dans d'autres entrées).
Quel est le problème?
Que vous frappiez deux fois la base de données si vous ne le faites pas dans le bon ordre (par exemple, si vous restituez le nombre d'éléments dans une table au-dessus de la table rendue, il y aura effectivement 2 appels envoyés à la base de données).
la source
Les stratégies suivantes appellent toutes la base de données pour effectuer une
COUNT(*)
requête.Ce qui suit n'est pas aussi efficace qu'il charge tous les enregistrements de la base de données dans Ruby, qui compte ensuite la taille de la collection.
Si vos modèles ont des associations et que vous souhaitez trouver le nombre d'objets appartenant (par exemple
@customer.orders.size
), vous pouvez éviter les requêtes de base de données (lectures sur disque). Utilisez un cache de compteur et Rails gardera la valeur du cache à jour et renverra cette valeur en réponse à lasize
méthode.la source
Model.all.size
etModel.all.count
génèrent unecount
requête dans Rails 4 et supérieur. Le véritable avantage desize
ne génère pas la requête de comptage si l'association est déjà chargée. Dans Rails 3 et ci-dessous, je pense que ceModel.all
n'est pas une relation, donc tous les enregistrements sont déjà chargés. Cette réponse est peut-être obsolète et je suggère de la supprimer.J'ai recommandé d'utiliser la fonction taille.
Considérez ces deux modèles. Le client a de nombreuses activités client.
Si vous utilisez un: counter_cache sur une association has_many, la taille utilisera directement le nombre mis en cache et ne fera aucune requête supplémentaire.
Prenons un exemple: dans ma base de données, un client a 20 000 activités client et j'essaie de compter le nombre d'enregistrements des activités client de ce client avec chacune des méthodes de comptage, de longueur et de taille. ci-dessous le rapport de référence de toutes ces méthodes.
j'ai donc trouvé que l'utilisation de: counter_cache Size est la meilleure option pour calculer le nombre d'enregistrements.
la source