¿Qué forma de contar una cantidad de filas debería ser más rápida en MySQL?
Esta:
SELECT COUNT(*) FROM ... WHERE ...
O la alternativa:
SELECT 1 FROM ... WHERE ...
// and then count the results with a built-in function, e.g. in PHP mysql_num_rows()
Uno pensaría que el primer método debería ser más rápido, ya que este es claramente el territorio de la base de datos y el motor de la base de datos debería ser más rápido que cualquier otra persona al determinar cosas como esta internamente.
mysql
performance
Franz
fuente
fuente
SELECT 1
y noSELECT *
. ¿Hay una diferencia?mysql_query()
, por ejemplo, todo el conjunto de resultados se envía a PHP desde MySQL, independientemente de lo que hacer con esos datos.Respuestas:
Cuando
COUNT(*)
tenga en cuenta los índices de columna, será el mejor resultado. Mysql con el motor MyISAM en realidad almacena el recuento de filas, no cuenta todas las filas cada vez que intenta contar todas las filas. (basado en la columna de la clave principal)Usar PHP para contar filas no es muy inteligente, porque tienes que enviar datos de mysql a php. ¿Por qué hacerlo cuando puedes lograr lo mismo en el lado de mysql?
Si
COUNT(*)
es lento, debe ejecutarEXPLAIN
la consulta y verificar si los índices se usan realmente y dónde deben agregarse.La siguiente no es la forma más rápida, pero hay un caso en el
COUNT(*)
que realmente no encaja: cuando comienza a agrupar los resultados, puede tener un problema, dondeCOUNT
realmente no cuenta todas las filas.La solución es
SQL_CALC_FOUND_ROWS
. Esto generalmente se usa cuando está seleccionando filas pero aún necesita saber el recuento total de filas (por ejemplo, para la paginación). Cuando seleccione filas de datos, simplemente agregue laSQL_CALC_FOUND_ROWS
palabra clave después de SELECT:Una vez que haya seleccionado las filas necesarias, puede obtener el recuento con esta única consulta:
FOUND_ROWS()
debe llamarse inmediatamente después de la consulta de selección de datos.En conclusión, todo se reduce a cuántas entradas tiene y qué hay en la declaración WHERE. Realmente debería prestar atención a cómo se utilizan los índices, cuando hay muchas filas (decenas de miles, millones y más).
fuente
MyISAM
almacena el recuento de filas. Otros motores de almacenamiento comoInnoDB
no almacenan recuentos de filas y contarán todas las filas cada vez .SELECT 1 FROM ... LIMIT 1
oSELECT COUNT(*) FROM ...
?WHERE
cláusula.SELECT COUNT(*) FROM ...
puede llevar un tiempo considerable, dependiendo de lo que se deba escanear (por ejemplo, una tabla muy grande o un índice de millones / miles de millones / billones de filas).SELECT 1 FROM ... LIMIT 1
regresa inmediatamente porque lo está limitando a la primera fila.Después de hablar con mis compañeros, Ricardo nos dijo que la forma más rápida es:
Pero debes recordar que el resultado puede no ser exacto.
También puede usarlo desde la línea de comando:
Más información: http://dev.mysql.com/doc/refman/5.7/en/show-table-status.html
Y puede encontrar una discusión completa en mysqlperformanceblog
fuente
SHOW TABLE STATUS
(o su equivalenteSELECT
eninformation_schema
) es rápido, pero no maneja unaWHERE
cláusula. Es preciso para MyISAM, pero impreciso (a veces con un factor de 2) para InnoDB.Gran pregunta, grandes respuestas. Aquí hay una forma rápida de hacer eco de los resultados si alguien está leyendo esta página y falta esa parte:
fuente
as count
?id
es confuso a primera vista.Esta consulta (que es similar a la que publicó bayuah ) muestra un buen resumen del recuento de todas las tablas dentro de una base de datos: (versión simplificada del procedimiento almacenado de Ivan Cachicatari que recomiendo encarecidamente).
Ejemplo:
fuente
information_schema
no es el mismo que el devuelto porSELECT count(*) FROM
en caso de que se use InnoDB. Si necesita un valor estricto, tenga en cuenta que este método proporciona un valor estricto solo con tablas MyISAM. Con InnoDB, el número de filas es una aproximación aproximada.Siempre he entendido que lo siguiente me dará los tiempos de respuesta más rápidos.
fuente
SELECT 1 ...
volverá tantas filas como elWHERE
yLIMIT
piden, y todos ellos serán "1".show table status like '<TABLE NAME>'
Esto será mucho más rápido.WHERE
cláusula. Y, para InnoDB, es solo una estimación.Si necesita obtener el recuento de todo el conjunto de resultados, puede adoptar el siguiente enfoque:
Normalmente, esto no es más rápido que el uso,
COUNT
aunque uno podría pensar que es el caso contrario porque está haciendo el cálculo internamente y no envía los datos al usuario, por lo que se sospecha una mejora en el rendimiento.Hacer estas dos consultas es bueno para la paginación para obtener totales, pero no particularmente para usar
WHERE
cláusulas.fuente
Hice algunos puntos de referencia para comparar el tiempo de ejecución de
COUNT(*)
vsCOUNT(id)
(id es la clave principal de la tabla, indexada).Número de pruebas: 10 * 1000 consultas
Resultados:
COUNT(*)
es más rápido 7%VER GRÁFICO: gráfico de referencia
Mi consejo es utilizar:
SELECT COUNT(*) FROM table
fuente
COUNT(1)
, sería interesante ver algunos puntos de referencia allí ...Prueba esto:
fuente
select count(*) from table_name
o algo más. dba.stackexchange.com/questions/151769/…Quizás desee considerar hacer un
SELECT max(Id) - min(Id) + 1
. Esto solo funcionará si sus ID son secuenciales y las filas no se eliminan. Sin embargo, es muy rápido.fuente
EXPLAIN SELECT id FROM ....
hizo el truco para mí. y pude ver el número de filas debajo de larows
columna del resultado.fuente
Manejé tablas para el gobierno alemán con a veces 60 millones de registros.
Y necesitábamos saber muchas veces el total de filas.
Entonces, los programadores de bases de datos decidimos que en cada tabla hay un registro siempre el registro en el que se almacena el número total de registros. Actualizamos este número, dependiendo de INSERT o DELETE filas.
Intentamos todas las demás formas. Esta es, con mucho, la forma más rápida.
fuente
Una declaración count (*) con una condición where en la clave principal devolvió el recuento de filas mucho más rápido para mí evitando el escaneo completo de la tabla.
Esto fue mucho más rápido para mí que
fuente