PHP incluye la función para MySQL mysql_num_rows, que en base a un recurso procedente de una consulta MySQL, retorna un numérico que representa el total de registros que se han devuelto.

El sentido común indica que utilizar la consulta SQL usando COUNT(*) será probablemente algo más eficiente, basicamente por aquello de que todo lo relacionado con el manejo de los datos, lo gestiona mejor el propio SGBD.

Lo que yo no sabía, era que la diferencia fuera tan grande… Así, para una tabla con aproximadamente 50.000 artículos, el código con mysql_num_rows siguiente, ha requerido 0,175506 segundos, o un poco más de 5 consultas por segundo:

//Contar usando num_rows
$fInicio=microtime(true);
$sSQL="SELECT * FROM articulo ";
$rstListado=mysql_query($sSQL);
$iRows=mysql_num_rows($rstListado);
mysql_free_result($rstListado);
$fFinal=microtime(true);
echo "Contar num_rows: " . $iRows . "; Tiempo: " . ($fFinal-$fInicio) . "<br>";

Sobre los mismos datos, el equivalente usando la función COUNT, ha necesitado solamente 0,000182, lo que equivale a algo más de 5.000 consultas por segundo, es decir, casi 1000 veces más veloz que usando mysql_numrows:

//Contar usando COUNT
$fInicio=microtime(true);
$sSQL="SELECT COUNT(*) FROM articulo ";
$rstListado=mysql_query($sSQL);
$asListado=mysql_fetch_array($rstListado);
$iRows=$asListado[0];
mysql_free_result($rstListado);
$fFinal=microtime(true);
echo "Contar usando COUNT: " . $iRows . "; Tiempo: " . ($fFinal-$fInicio) . "<br>";

Muy bien, y ahora, ¿qué ocurriría si además de contarlos, necesitáramos obtenerlos? Aquí hay más dudas, pero la lógica dice que probablemente mysql_num_rows será más veloz, pues ejecutando una sola vez el SQL, obtenemos los datos y los contamos. Sería más o menos así:

//Contar y obtener con COUNT
$fInicio=microtime(true);
$sSQL="SELECT COUNT(*) FROM articulo ";
$rstListado=mysql_query($sSQL);
$asListado=mysql_fetch_array($rstListado);
$iRows=$asListado[0];
mysql_free_result($rstListado);
$sSQL="SELECT * FROM articulo ";
$rstListado=mysql_query($sSQL);
mysql_free_result($rstListado);
$fFinal=microtime(true);
echo "Contar y obtener con COUNT: " . $iRows . "; Tiempo: " . ($fFinal-$fInicio) . "<br>";

Sorprendentemente, a pesar de realizarse dos consultas, una de conteo y otra de obtención, el tiempo requerido ha sido de 0,169486 , que vienen a ser casi 6 consultas por segundo, es decir, más rápido que mysql_num_rows.

Sin duda, algo falla en la implementación de mysql_num_rows en PHP, que lo hace poco eficiente, por tanto ya sabéis, si solamente es para contar, mucho mejor COUNT. Si tenéis que contar y obtener, probablente, sea mejor también COUNT, aunque las pequeñas diferencias, pueden hacerlo variar en vuestros respectivos entornos.