W Railsach możesz znaleźć liczbę rekordów używając zarówno Model.size
i Model.count
. Jeśli masz do czynienia z bardziej złożonymi zapytaniami, czy jest jakaś korzyść z używania jednej metody nad drugą? Czym się różnią?
Na przykład mam użytkowników ze zdjęciami. Jeśli chcę wyświetlić tabelę użytkowników i liczbę ich zdjęć, czy uruchomienie wielu wystąpień user.photos.size
będzie szybsze lub wolniejsze niż user.photos.count
?
Dzięki!
size
dostosowuje się do sytuacji, w każdym razie, to co potrzeba jest tamlength
icount
w ogóle?size
można było do nich zadzwonić po nawiązaniu połączeniasize
(po określeniu, do którego należy zadzwonić).Comment.create(post_id: post.id)
Twojapost.comments.size
wola nie być aktualne, apost.comments.count
wola. Więc bądź ostrożny.company.devices.build(:name => "device1"); company.devices.build(:name => "device2")
wtedycompany.devices.size
i.length
będzie zawierać liczbę obiektów zbudowanych, ale nie zapisanych,.count
zgłosi tylko liczbę z bazy danych.Jak podają inne odpowiedzi:
count
wykonaCOUNT
zapytanie SQLlength
obliczy długość wynikowej tablicysize
spróbuje wybrać najbardziej odpowiedni z dwóch, aby uniknąć nadmiernych zapytańAle jest jeszcze jedna rzecz. Zauważyliśmy przypadek, w którym
size
działa inaczejcount
/length
zupełnie, i pomyślałem, że go udostępnić, ponieważ jest to rzadki wystarczy pominąć.Jeśli użyjesz atrybutu „as”
:counter_cache
whas_many
powiązaniu,size
użyje bezpośrednio pamięci podręcznej i w ogóle nie wykona dodatkowego zapytania.To zachowanie jest udokumentowane w Przewodnikach po Railsach , ale albo go przegapiłem za pierwszym razem, albo o nim zapomniałem.
źródło
_count
kolumna (bezcounter_cache: true
dyrektywy w sprawie powiązania). Zostało to naprawione w github.com/rails/rails/commit/e0cb21f5f7Czasami
size
„wybiera niewłaściwy” i zwraca skrót (cocount
by zrobiło)W takim przypadku użyj,
length
aby uzyskać liczbę całkowitą zamiast skrótu .źródło
tl; dr
count
.length
.size
...liczyć
Rozwiązuje problem z wysłaniem
Select count(*)...
zapytania do bazy danych. Droga, jeśli nie potrzebujesz danych, ale tylko liczbę.Przykład: liczba nowych wiadomości, łączna liczba elementów, gdy wyświetlana będzie tylko strona itp.
długość
Ładuje wymagane dane, tj. Zapytanie zgodnie z wymaganiami, a następnie po prostu je zlicza. Droga, jeśli korzystasz z danych.
Przykład: Podsumowanie w pełni załadowanej tabeli, tytuły wyświetlanych danych itp.
rozmiar
Sprawdza, czy dane zostały załadowane (tj. Już w szynach), jeśli tak, to po prostu je policz, w przeciwnym razie wywoła liczyć. (plus pułapki, wspomniane już w innych wpisach).
Jaki jest problem?
Że możesz uderzać w DB dwukrotnie, jeśli nie zrobisz tego we właściwej kolejności (np. Jeśli renderujesz liczbę elementów w tabeli nad renderowaną tabelą, do DB zostaną wysłane 2 wywołania).
źródło
Wszystkie poniższe strategie wywołują bazę danych w celu wykonania
COUNT(*)
zapytania.Poniższe nie jest tak wydajne, jak spowoduje załadowanie wszystkich rekordów z bazy danych do Ruby, co następnie zlicza rozmiar kolekcji.
Jeśli twoje modele mają powiązania i chcesz znaleźć liczbę przynależnych obiektów (np.
@customer.orders.size
), Możesz uniknąć zapytań do bazy danych (odczytów dysku). Użyj bufora licznika, a Railsy utrzymają wartość bufora na bieżąco i zwrócą tę wartość w odpowiedzi nasize
metodę.źródło
Model.all.size
iModel.all.count
wygenerowaćcount
zapytania w szynach 4 i powyżej. Prawdziwą zaletąsize
jest to, że nie generuje zapytania zliczającego, jeśli powiązanie jest już załadowane. W Railsach 3 i niższych uważam, żeModel.all
nie ma związku, dlatego wszystkie rekordy są już załadowane. Ta odpowiedź może być nieaktualna i sugeruję jej usunięcie.Polecam użycie funkcji rozmiaru.
Rozważ te dwa modele. Klient ma wiele działań klienta.
Jeśli użyjesz: counter_cache w powiązaniu has_many, rozmiar użyje bezpośrednio pamięci podręcznej i w ogóle nie wykona dodatkowego zapytania.
Rozważmy jeden przykład: w mojej bazie danych jeden klient ma 20 000 działań klienta i staram się policzyć liczbę zapisów działań klienta tego klienta za pomocą każdej metody liczenia, długości i rozmiaru. poniżej raportu porównawczego wszystkich tych metod.
więc odkryłem, że użycie: counter_cache Size jest najlepszą opcją do obliczenia liczby rekordów.
źródło