2013-02-10 3 views
2

En supposant qu'il existe 2 modèles appelés User et PostQuel est le "compte" ou la "longueur" le plus rapide?

Ce qui sera une meilleure performance (rapide) soit "Plan A" ou "Plan B"?

"Plan A"

contrôleur

@users = User.find_all_by_country(params[:country]) 
@posts = Post.find_all_by_category(params[:category]) 

vue

<%= @users.count.to_s %> 
<%= @posts.count.to_s %> 

"Plan B"

contrôleur

@users = User.find_all_by_country(params[:country]) 
@posts = Post.find_all_by_category(params[:category]) 

vue

<%= @users.length.to_s %> 
<%= @posts.length.to_s %> 
+2

Qu'est-ce que arrive quand vous l'essayez? Lequel est le plus rapide? –

+0

Eh bien. Je dois sans doute à la recherche comment les premiers – Foo

Répondre

11

Dans ruby, count, length et size tous font à peu près la même chose en ce qui concerne les tableaux. Voir here pour plus d'informations.

Lorsque vous utilisez objets ActiveRecord, cependant, count est mieux que length et size est encore mieux.

find_all_by_countryfind_all_by_country renvoie un tableau binaire, vous ne devriez donc pas utiliser cette méthode (car elle renvoie toujours un tableau). Au lieu de cela, utilisez where(country: params[:country]).

Je vais laisser Code School diapositive nº 93 parler de lui-même (et j'espère qu'ils ne se fâchent pas de moi pour le reproduire ici).

enter image description here

Juste au cas où l'image est prise vers le bas, au fond:

  1. length tire toujours tous les enregistrements et les appels.longueur sur le tableau - mauvais

  2. count toujours fait une requête de comptage - bonne

  3. size regarde le cache si vous avez un compteur de cache, ne sinon un compte requête - le meilleur

+0

Merci !!!. C'est une réponse parfaite. Merci beaucoup :) Dans mon application. Je supprime parfois des enregistrements sur phpMyAdmin. C'est pourquoi il ne supprimera pas les enregistrements liés de sorte que mon cache de compteur sera foiré. C'est la raison pour laquelle je ne veux pas utiliser le cache de compteur. Dans cette situation, utiliseriez-vous simplement la longueur à la place? – Foo

+0

@foo Notez que cette réponse est ** ** mauvaise, comme vous n'êtes pas invoquez '' length' ou count' sur une relation ActiveResource, mais sur un simple tableau ancien Ruby. Les méthodes longueur/nombre/taille dont parle la diapositive ne sont pas les mêmes que celles que vous utilisez. – meagar

+0

@meagar Dans ma compréhension, une fois que je récupérons les enregistrements par ce '@users = User.find_all_by_country (params [: pays])', il ne sera pas invoquer la requête SQL, même si je fais cela en vue. '<% = @ Users.length.to_s%>' – Foo

1

Les deux seront les mêmes, count sans argument et length sont identiques que vous les invoquez sur un tableau Ruby (retourné par la méthode find_* magique), et pas un objet ActiveRecord. Cela dit, les deux méthodes sont pire pour ce faire, si vous êtes simplement intéressé par le nombre d'enregistrements correspondants.

Au lieu d'instancier le résultat complet situé juste à trouver sa longueur, utilisez .count sur une relation ActiveRecord réelle:

@num_users = User.where(country: params[:country]).count 
@num_posts = Post.where(category: params[:category]).count 

Cela exécutera en fait comme select count(*) from au lieu d'un select * from complet, qui sera beaucoup plus rapide en fonction sur le nombre de résultats.

+0

de référence Merci comment voulez-vous faire plus rapidement si vous n'utilisez counter_cache – Foo

+1

@foo Ce que vous fait croire que vous pouvez le faire plus vite? '.length' et' .count' sont si rapides que vous ne pouvez probablement pas les mesurer. Si vous voulez juste trouver le nombre d'enregistrements correspondants, voir ma réponse modifiée. – meagar

+0

Merci pour votre réponse. J'imaginais simplement que plus de 10000 personnes chargent la page en même temps. Ensuite, il y aura beaucoup de postes qui ont des commentaires pour chacun. Évidemment, il a le nombre de commentaires que chaque poste a. Je veux montrer ces nombres avec le compte. Pas de cache de compteur pour une raison quelconque. S'il y a 50 messages affichés dans la page. 10000 personnes x 50 messages seront en cours d'exécution. Je voulais donc accélérer le plus vite possible. – Foo

Questions connexes