ActiveRecord: tamaño vs recuento
En Rails, puede encontrar el número de registros usando Model.size
y Model.count
. Si está tratando con consultas más complejas, ¿hay alguna ventaja en 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, ¿ejecutar muchas instancias de user.photos.size
será más rápido o más lento que user.photos.count
?
Gracias!
4 answers
Deberías leer que, sigue siendo válido.
Adaptarás la función que utilices en función de tus necesidades.
Básicamente:
-
Si ya carga todas las entradas, por ejemplo
User.all
, entonces debe usarlength
para evitar otra consulta de base de datos -
Si no tiene nada cargado, use
count
para hacer una consulta de recuento en su db -
Si no desea molestarse con estas consideraciones, use
size
que se adaptará
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-10 22:15:03
Como dicen las otras respuestas:
-
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 donde size
actúa de manera diferente a count
/length
en conjunto, y pensé en compartirlo ya que es lo suficientemente raro como para ser pasado por alto.
-
Si utiliza un
:counter_cache
en unhas_many
asociación,size
utilizará el recuento en caché directamente, y no hacer una consulta adicional en absoluto.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 Rails, pero o lo perdí la primera vez o lo olvidé.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-09 11:33:17
A veces size
"elige el equivocado" y devuelve un hash (que es lo que haría count
)
En ese caso, use length
para obtener un integer en lugar de hash.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-28 09:32:57
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 ya que 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 consultas de base de datos (lecturas de disco). Utilice un contador de caché y Rails mantendrá el valor de caché actualizado y devolverá ese valor en respuesta al método size
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-26 19:46:03