MySQL: la manera más rápida de contar el número de filas

¿Qué manera de contar un número de filas debería ser más rápido en MySQL?

Esta:

SELECT COUNT(*) FROM ... WHERE ... 

O bien, la alternativa:

 SELECT 1 FROM ... WHERE ... // and then count the results with a built-in function, eg in PHP mysql_num_rows() 

Uno podría pensar 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 nadie al determinar cosas como esta internamente.

Cuando COUNT(*) toma en cuenta los índices de columnas, entonces será el mejor resultado. Mysql con el motor MyISAM actualmente 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 el COUNT(*) es lento, debe ejecutar EXPLAIN en la consulta y verificar si los índices realmente se usan y dónde deben agregarse.


La siguiente no es la forma más rápida, pero hay un caso en el que COUNT(*) no encaja realmente: cuando comienzas a agrupar resultados, puedes encontrar un problema, donde COUNT realmente no cuenta todas las filas.

La solución es SQL_CALC_FOUND_ROWS . Esto generalmente se usa cuando selecciona filas, pero aún necesita conocer el recuento total de filas (por ejemplo, para paginación). Cuando selecciona filas de datos, simplemente agregue la palabra clave SQL_CALC_FOUND_ROWS después de SELECT:

 SELECT SQL_CALC_FOUND_ROWS [needed fields or *] FROM table LIMIT 20 OFFSET 0; 

Después de haber seleccionado las filas necesarias, puede obtener el recuento con esta única consulta:

 SELECT FOUND_ROWS(); 

FOUND_ROWS() debe llamar a FOUND_ROWS() inmediatamente después de la consulta de selección de datos.


En conclusión, todo en realidad se reduce a la cantidad de entradas que tiene y lo que está en la statement WHERE. Realmente debe prestar atención a cómo se utilizan los índices, cuando hay muchas filas (decenas de miles, millones y más).

Después de hablar con mis compañeros de equipo, Ricardo nos dijo que la forma más rápida es:

 show table status like '' \G

Pero debes recordar que el resultado puede no ser exacto.

Puedes usarlo desde la línea de comando también:

 $ mysqlshow --status  

Más información: http://dev.mysql.com/doc/refman/5.7/en/show-table-status.html

Y puedes encontrar una discusión completa en mysqlperformanceblog

Gran pregunta, excelentes respuestas. Esta es una forma rápida de hacer eco de los resultados si alguien está leyendo esta página y le falta esa parte:

 $counter = mysql_query("SELECT COUNT(*) AS id FROM table"); $num = mysql_fetch_array($counter); $count = $num["id"]; echo("$count"); 

Siempre he entendido que el siguiente me dará los tiempos de respuesta más rápidos.

 SELECT COUNT(1) FROM ... WHERE ... 

Esta consulta (que es similar a lo que Bayuah publicó) muestra un buen resumen de todas las tablas dentro de una base de datos: (versión simplificada del procedimiento almacenado por Ivan Cachicatari que recomiendo encarecidamente).

SELECT TABLE_NAME AS 'Table Name', TABLE_ROWS AS 'Rows' FROM information_schema.TABLES WHERE TABLES.TABLE_SCHEMA = ' YOURDBNAME ' AND TABLES.TABLE_TYPE = 'BASE TABLE' ;

Ejemplo:

+-----------------+---------+ | Table Name | Rows | +-----------------+---------+ | some_table | 10278 | | other_table | 995 |

Si necesita obtener el recuento de todo el conjunto de resultados, puede tomar el siguiente enfoque:

 SELECT SQL_CALC_FOUND_ROWS * FROM table_name LIMIT 5; SELECT FOUND_ROWS(); 

Esto normalmente no es más rápido que el uso de COUNT aunque uno podría pensar que es el caso contrario porque hace el cálculo internamente y no envía los datos al usuario, por lo que se sospecha la mejora del rendimiento.

Hacer estas dos consultas es bueno para la paginación para obtener totales, pero no particularmente para usar las cláusulas WHERE .

Hice algunos benchmarks para comparar el tiempo de ejecución de COUNT(*) vs COUNT(id) (id es la clave principal de la tabla – indexada).

Número de ensayos: 10 * 1000 consultas

Resultados: COUNT(*) es más rápido 7%

VER GRÁFICO: punto de referencia

Mi consejo es usar: SELECT COUNT(*) FROM table

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.

Prueba esto:

 SELECT table_rows "Rows Count" FROM information_schema.tables WHERE table_name="Table_Name" AND table_schema="Database_Name"; 

Manejé tablas para el gobierno alemán con 60 millones de registros.

Y necesitábamos saber muchas veces las filas totales.

Así que los progtwigdores de bases de datos decidimos que en cada tabla se registra siempre uno el registro en el que se almacenan los números totales de registros. Actualizamos este número, dependiendo de INSERTAR o ELIMINAR filas.

Probamos todas las otras formas. Esta es, de lejos, la manera más rápida.

EXPLAIN SELECT id FROM .... me gustó el truco. y pude ver el número de filas debajo de la columna de rows del resultado.