In Rails finden Sie die Anzahl der Datensätze mit Model.size
und Model.count
. Wenn Sie mit komplexeren Abfragen arbeiten, hat die Verwendung einer Methode gegenüber der anderen einen Vorteil? Wie unterscheiden sie sich?
Zum Beispiel habe ich Benutzer mit Fotos. Wenn ich eine Tabelle mit Benutzern anzeigen möchte und wie viele Fotos sie haben, werden viele Instanzen user.photos.size
schneller oder langsamer ausgeführt als user.photos.count
?
Vielen Dank!
size
passt sich an die Situation sowieso, was dann notwendig ist , da fürlength
undcount
überhaupt?size
können sie angerufen werden, wenn Sie den Anruf tätigensize
(nachdem festgelegt wurde, welcher angerufen werden soll).Comment.create(post_id: post.id)
ist Ihr Datensatzpost.comments.size
nicht auf dem neuesten Standpost.comments.count
. Also sei einfach vorsichtig.company.devices.build(:name => "device1"); company.devices.build(:name => "device2")
,company.devices.size
und.length
die Anzahl der Objekte enthält, die Sie erstellt, aber nicht gespeichert haben,.count
wird nur die Anzahl aus der Datenbank gemeldet.In den anderen Antworten heißt es:
count
führt eine SQL-COUNT
Abfrage durchlength
berechnet die Länge des resultierenden Arrayssize
wird versuchen, die am besten geeignete der beiden auszuwählen, um übermäßige Abfragen zu vermeidenAber es gibt noch eine Sache. Wir bemerkten einen Fall , wo
size
anders wirkt aufcount
/length
zusammen, und ich dachte ich , es würde teilen , da es selten genug ist , übersehen zu werden.Wenn Sie a
:counter_cache
für einehas_many
Zuordnung verwenden,size
wird die zwischengespeicherte Anzahl direkt verwendet und es wird überhaupt keine zusätzliche Abfrage durchgeführt.Dieses Verhalten ist in den Rails Guides dokumentiert , aber ich habe es entweder beim ersten Mal verpasst oder vergessen.
quelle
_count
Spalte vorhanden ist (ohne diecounter_cache: true
Anweisung zur Zuordnung). Dies wurde in github.com/rails/rails/commit/e0cb21f5f7Manchmal
size
"wählt den falschen aus" und gibt einen Hash zurück (wascount
tun würde)Verwenden Sie
length
in diesem Fall, um eine Ganzzahl anstelle von Hash abzurufen .quelle
tl; dr
count
.length
.size
...Anzahl
Beschließt, eine
Select count(*)...
Abfrage an die Datenbank zu senden . Der richtige Weg, wenn Sie nicht die Daten, sondern nur die Anzahl benötigen.Beispiel: Anzahl neuer Nachrichten, Gesamtzahl der Elemente, wenn nur eine Seite angezeigt werden soll usw.
Länge
Lädt die erforderlichen Daten, dh die Abfrage nach Bedarf, und zählt sie dann einfach. Der richtige Weg, wenn Sie die Daten verwenden.
Beispiel: Zusammenfassung einer vollständig geladenen Tabelle, Titel der angezeigten Daten usw.
Größe
Es prüft, ob die Daten geladen wurden (dh bereits in Schienen), wenn dies der Fall ist, und zählt sie dann einfach, andernfalls wird count aufgerufen. (plus die Fallstricke, die bereits in anderen Einträgen erwähnt wurden).
Was ist das Problem?
Dass Sie die Datenbank möglicherweise zweimal treffen, wenn Sie dies nicht in der richtigen Reihenfolge tun (z. B. wenn Sie die Anzahl der Elemente in einer Tabelle über der gerenderten Tabelle rendern, werden effektiv 2 Aufrufe an die Datenbank gesendet).
quelle
Die folgenden Strategien rufen alle die Datenbank auf, um eine
COUNT(*)
Abfrage durchzuführen .Das Folgende ist nicht so effizient, da alle Datensätze aus der Datenbank in Ruby geladen werden, das dann die Größe der Sammlung zählt.
Wenn Ihre Modelle Assoziationen haben und Sie die Anzahl der zugehörigen Objekte ermitteln möchten (z. B.
@customer.orders.size
), können Sie Datenbankabfragen (Festplattenlesevorgänge) vermeiden. Verwenden Sie einen Zähler-Cache, und Rails hält den Cache-Wert auf dem neuesten Stand und gibt diesen Wert als Antwort auf diesize
Methode zurück.quelle
Model.all.size
undModel.all.count
generieren einecount
Abfrage in Rails 4 und höher. Der eigentliche Vorteil vonsize
ist, dass die Zählabfrage nicht generiert wird, wenn die Zuordnung bereits geladen ist. In Rails 3 und darunter glaube ich, dassModel.all
es sich nicht um eine Beziehung handelt, daher sind alle Datensätze bereits geladen. Diese Antwort ist möglicherweise veraltet und ich schlage vor, sie zu löschen.Ich habe empfohlen, die Größenfunktion zu verwenden.
Betrachten Sie diese beiden Modelle. Der Kunde hat viele Kundenaktivitäten.
Wenn Sie einen: counter_cache für eine has_many-Zuordnung verwenden, verwendet size die zwischengespeicherte Anzahl direkt und führt überhaupt keine zusätzliche Abfrage durch.
Betrachten Sie ein Beispiel: In meiner Datenbank hat ein Kunde 20.000 Kundenaktivitäten und ich versuche, die Anzahl der Datensätze der Kundenaktivitäten dieses Kunden mit jeder Zähl-, Längen- und Größenmethode zu zählen. hier unten der Benchmark-Bericht aller dieser Methoden.
Daher fand ich, dass die Verwendung von: counter_cache Size die beste Option ist, um die Anzahl der Datensätze zu berechnen.
quelle