ActiveRecord: размер vs count

В Rails вы можете найти количество записей, используя как Model.size, так и Model.count. Если вы имеете дело с более сложными запросами, есть ли преимущество в использовании одного метода над другим? Как они отличаются?

Например, у меня есть пользователи с фотографиями. Если я хочу показать таблицу пользователей и сколько у них фотографий, будет работать много экземпляров user.photos.size быстрее или медленнее, чем user.photos.count?

Спасибо!

Ответ 1

Вы должны прочитать который, он все еще действителен.

Вы будете адаптировать функцию, которую вы используете, в зависимости от ваших потребностей.

В принципе:

  • если вы уже загрузили все записи, скажем User.all, тогда вы должны использовать length, чтобы избежать другого запроса db

  • Если вы ничего не загрузили, используйте count, чтобы сделать запрос count на вашем db

  • Если вы не хотите беспокоиться об этих соображениях, используйте size, который будет адаптировать

Ответ 2

Как утверждают другие ответы:

  • count выполнит запрос SQL count
  • length будет вычислять длину результирующего массива
  • size попытается выбрать наиболее подходящий из двух, чтобы избежать чрезмерных запросов

Но есть еще одна вещь. Мы заметили случай, когда size действует по-разному на count/length в целом, и я думал, что поделюсь им, так как он достаточно редок, чтобы его не замечали.

  • Если вы используете ассоциацию :counter_cache в has_many, size будет использовать кеш-счет напрямую, а не делать дополнительный запрос вообще.

    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
    

Это описано в Rails Guides, но я либо пропустил его в первый раз, либо забыл об этом.

Ответ 3

Иногда size "выбирает неправильный" и возвращает хеш (что будет делать count)

В этом случае используйте length, чтобы получить целое число вместо хеша.

Ответ 4

Следующие стратегии делают вызов в базу данных для выполнения запроса COUNT(*).

Model.count

Model.all.size

records = Model.all
records.count

Ниже приведена не такая эффективная задача, как загрузка всех записей из базы данных в Ruby, которая затем подсчитывает размер коллекции.

records = Model.all
records.size

Если ваши модели имеют ассоциации и вы хотите найти количество принадлежащих им объектов (например, @customer.orders.size), вы можете избежать запросов к базе данных (чтение дисков). Используйте кеш-счетчик , а Rails сохранит значение кеша в актуальном состоянии и вернет это значение в ответ на метод size.