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
.