Korrekt - wenn eine Sammlung oder ein kompliziertes Objekt mit vielen Assoziationen geladen wird, kann ein kostspieliger Aufruf zum eifrigen Laden aller Objekte und Verknüpfungen durch einen schnellen, einfachen Aufruf vermieden werden. Die rails guide for caching hat ein gutes Beispiel, aber es ist ein bisschen aufgeteilt. Mit Blick auf dem gemeinsamen Anwendungsfall eine Sammlung Cachen (dh der Index Aktion in Rails):
<% cache("products/all-#{Product.maximum(:updated_at).try(:to_i)}") do %>
All available products:
<% Product.all.each do |p| %>
<% cache(p) do %>
<%= link_to p.name, product_url(p) %>
<% end %>
<% end %>
<% end %>
Dieses (verkürzt) Beispiel tut 1 einfacher DB-Aufruf Product.maximum(:updated_at)
Product.all
machte einen viel teurer Anruf zu vermeiden.
Für einen kalten Cache (die zweite Frage) ist es wichtig, N + 1 durch eifriges Laden assoziierter Objekte zu vermeiden. Wir wissen jedoch, dass wir diesen teuren Anruf tätigen müssen, da der erste Cache-Lesevorgang für die Sammlung fehlgeschlagen ist. In Rails erfolgt dies normalerweise mit includes
. Wenn ein Product
zu viele Order
s gehört, dann so etwas wie:
<% cache("products/all-#{Product.maximum(:updated_at).try(:to_i)}") do %>
All available products:
<% Product.includes(:orders).all.each do |p| %>
<% cache(p) do %>
<%= link_to p.name, product_url(p) %>
Bought at:
<ul>
<% p.orders.each do |o| %>
<li><%= o.created_at.to_s %></li>
<% end %>
</ul>
<% end %>
<% end %>
<% end %>
Im kalten Cache Fall noch wir einen Cache für die Sammlung und jedes Mitglied lesen tun, aber in der teilweise warmen Cache Fall werden wir Rendering überspringen für einen Teil der Mitglieder. Beachten Sie, dass diese Strategie auf einer s Assoziationen basiert, die korrekt auf touch
eingerichtet wird, wenn verknüpfte Objekte aktualisiert werden.
Update: This blog post beschreibt ein komplexeres Muster zur weiteren Optimierung der Gebäudemeldungen für teilweise zwischengespeicherte Sammlungen. Anstatt die gesamte Sammlung neu zu erstellen, ruft sie massenhaft alle verfügbaren zwischengespeicherten Werte ab, führt dann eine Massenabfrage nach den verbleibenden Werten durch (und aktualisiert den Cache). Dies ist auf verschiedene Arten hilfreich: Das Lesen des Massencaches ist schneller als das Lesen von N + 1-Caches, und die Massenabfrage an die Datenbank zum Erstellen des Caches ist ebenfalls kleiner.