Une meilleure performance sur les associations
-
21-08-2019 - |
Question
En ce moment j'ai une table appelée campagnes qui a de nombreux succès, si je l'appelle dire:
Campaign.find(30).hits
Ce qui prend 4 secondes, ou 4213 ms.
Si j'appelle ceci:
campaign = Campaign.find(30) campaign.hits.count
chargement est-il encore tous les coups, puis compter? Ou faut-il voir je compte et évite le chargement de tous les coups? (Qui est actuellement 300,000+ lignes).
J'essaie de trouver une façon intelligente de charger / compte mes coups. Je pense à l'ajout d'une méthode pour mon modèle Campaign.rb, comme:
def self.total_hits find :first, :select => 'COUNT(id) as hits', :conditions => ["campaign_id = ?", self.id] end
Je sais que cette requête ne se charge pas de la table hits
, mais qui est juste un exemple de compter à partir d'une requête en auto, à accolées Ruby on Rails faire ça pour moi.
Est-ce que cette requête memcache plus effecient? (Je l'ai en cours d'exécution, mais ne semble pas être mieux / plus rapide / plus lent, juste la même vitesse.)
def self.hits Rails.cache.fetch("Campaign_Hits_#{self.campaign_id}", :expires_in => 40) { find(:first, :select => 'COUNT(id) as hits', :conditions => ["campaign_id = ?", self.campaign_id]).hits } end
Toute suggestion serait génial!
La solution
Que diriez-vous:
Campaign.find(30).hits.count
Vous pouvez également envisager d'ajouter ce qui suit dans hit.rb
(en supposant un à plusieurs entre les campagnes et les hits).
belongs_to :campaign, :counter_cache => true
Vous devez ensuite une colonne dans la table appelée campaigns
hits_count
. Cela évitera de frapper tout à fait si vous hits
êtes seulement obtenir le nombre.
Vous pouvez consulter le API pour toute la diminution des effectifs.
Autres conseils
Mon ActiveRecord peut-être un peu rouillé, alors pardonnez-moi si oui, mais IIRC est au moins Campaign.find(30).hits
deux requêtes distinctes. Comment fait-on Campaign.find(30, :include => [ :hits ]).hits
? Cela devrait effectuer une seule requête.