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?

Dzięki!
Author: user2262149, 2011-05-21

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ą

 294
Author: apneadiving,
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 SQL COUNT
  • 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/lengthw 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 na has_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.

 69
Author: lime,
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.

 7
Author: jvalanen,
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.

 2
Author: Dennis,
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