ruby on rails - rails - ActiveRecord: tamaño contra recuento
ruby on rails tutorial (4)
En Rails, puede encontrar la cantidad de registros usando Model.size
y Model.count
. Si se trata de consultas más complejas, ¿hay alguna ventaja al usar un método sobre el otro? ¿En qué se diferencian?
Por ejemplo, tengo usuarios con fotos. Si quiero mostrar una tabla de usuarios y cuántas fotos tienen, ¿se ejecutarán muchas instancias de user.photos.size
más rápido o más lento que user.photos.count
?
¡Gracias!
A veces el size
"elige el incorrecto" y devuelve un hash (que es lo que haría la cuenta)
En ese caso, use length
para obtener un entero en lugar de hash .
Como las otras respuestas dicen:
-
count
realizará una consulta SQLCOUNT
-
length
calculará la longitud de la matriz resultante -
size
intentará elegir el más apropiado de los dos para evitar consultas excesivas
Pero hay una cosa más. Notamos un caso en el que el size
actúa de manera diferente para count
/ length
completo, y pensé que lo compartiría, ya que es lo suficientemente raro como para pasarlo por alto.
Si usa un
:counter_cache
en una asociaciónhas_many
, elsize
usará el recuento en caché directamente y no hará ninguna consulta adicional.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
Este comportamiento está documentado en las Guías de Rails , pero o lo perdí la primera vez o lo olvidé.
Deberías leer that , sigue siendo válido.
Adaptará la función que usa según sus necesidades.
Básicamente:
si ya carga todas las entradas, diga
User.all
, entonces debe usarlength
para evitar otra consulta dbsi no tiene nada cargado, use
count
para hacer una consulta de conteo en su dbsi no quiere molestarse con estas consideraciones, use el
size
que se adaptará
Todas las siguientes estrategias hacen una llamada a la base de datos para realizar una consulta COUNT(*)
.
Model.count
Model.all.size
records = Model.all
records.count
Lo siguiente no es tan eficiente como cargar todos los registros de la base de datos en Ruby, que luego cuenta el tamaño de la colección.
records = Model.all
records.size
Si sus modelos tienen asociaciones y desea encontrar el número de objetos pertenecientes (por ejemplo, @customer.orders.size
), puede evitar las consultas de la base de datos (lecturas de disco). Use un contador de caché y Rails mantendrá el valor de caché actualizado, y devolverá ese valor en respuesta al método de size
.