ActiveRecord: size vs count
W Rails można znaleźć liczbę rekordów używając 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ę pokazać tabelę użytkowników i liczbę ich zdjęć, czy uruchamianie wielu instancji user.photos.size
będzie szybsze lub wolniejsze niż user.photos.count
?
4 answers
Powinieneś przeczytać , że , to nadal jest ważne.
Dostosujesz funkcję, której używasz w zależności od potrzeb.
W zasadzie:
-
Jeśli już załadowałeś wszystkie wpisy, powiedzmy
User.all
, powinieneś użyćlength
, aby uniknąć kolejnego zapytania db -
Jeśli nic nie zostało załadowane, użyj
count
, aby wykonać zapytanie count na Twoim db -
Jeśli nie chcesz zawracać sobie głowy tymi rozważaniami, użyj
size
, które dostosują
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-10 22:15:03
Jak inne odpowiedzi stwierdzają:
-
count
wykona zapytanie SQLCOUNT
-
length
obliczy długość tablicy wynikowej -
size
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 inaczej niż count
/length
w sumie, i pomyślałem, że podzielę się nim, ponieważ jest na tyle Rzadki, że można go przeoczyć.
-
Jeśli używasz
:counter_cache
nahas_many
Asocjacja,size
użyje buforowanej liczby bezpośrednio i w ogóle nie będzie wywoływać dodatkowych zapytań.class Image < ActiveRecord::Base belongs_to :product, counter_cache: true end class Product < ActiveRecord::Base has_many :images end > product = Product.first # query, load product into memory > product.images.size # no query, reads the :images_count column > product.images.count # query, SQL COUNT > product.images.length # query, loads images into memory
To zachowanie jest udokumentowane w prowadnicach Rails , Ale albo przegapiłem to za pierwszym razem, albo o tym zapomniałem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-09 11:33:17
Czasami size
"wybiera zły" i zwraca hash (czyli to, co zrobiłby count
)
W takim przypadku użyj length
, aby uzyskać liczbę całkowitą zamiast hash.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-28 09:32:57
Poniższe strategie wywołują do bazy danych wywołanie zapytania COUNT(*)
.
Model.count
Model.all.size
records = Model.all
records.count
Poniższy tekst nie jest tak wydajny, ponieważ załaduje wszystkie rekordy z bazy danych do Rubiego, który następnie zlicza rozmiar kolekcji.
records = Model.all
records.size
Jeśli twoje modele mają skojarzenia i chcesz znaleźć liczbę należących obiektów (np. @customer.orders.size
), możesz uniknąć zapytań do bazy danych (odczytów na dysku). Użyj counter cache i Rails utrzyma aktualną wartość cache i zwróci tę wartość w odpowiedzi na metodę size
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-26 19:46:03