Category: Php

En muchas ocasiones, al trabajar en equipo con otros programadores, he encontrado casos en los que por desconocimiento o por costumbre se tiende hacer código ineficiente o al menos no tan eficiente como podría serlo, desperdiciando recursos y/o aumentando el tiempo de ejecución.

Para la mayoría de programadores experimentados, estas practicas son mas conocidas, pero aun así no esta de más recordarlas.

Bajo este criterio, comenzamos un nuevo “hilo” de artículos, que he titulado “trucos de perro viejo”, iré añadiendo según me encuentre este tipo de casos o bien recuerde alguno que me encontrara en el pasado.

Para comenzar, un caso que he encontrado ya múltiples veces cuando realizamos un listado, con el típico botón/link de “ver más”.

No usar “count” para listados con “ver más”

Por ejemplo un listado con los últimos 10 artículos de una web, con un link de ver más.

He perdido la cuenta de las ocasiones que al heredar código ajeno, me encuentro implementaciones ineficientes, basadas en dos query, una para mostrar los X resultados del listado y una de “count” para saber, si debe aparecer el botón de ver más o no.

<?php
$lSQL ='SELECT * FROM articulos ORDER BY FechaPublic DESC LIMIT 10';
$lSQLCount = 'SELECT COUNT(*) NumReg FROM articulos';
//Obtenemos los registros
$resultado = $mysqli->query($lSQL);
$resultado->data_seek(0);
while($fila=$resultado->fetch_assoc()){
//Codigo de pintado de la pagina linea
}
//Miramos si tenemos que añadir el link
$resultado=$mysqli->query($lSQLCount);
$fila=$resultado->fetch_assoc();
if($fila['NumReg']>10){
//Cremos el link
}

…

Cuando se puede resolver de forma mucho más elegante y eficiente con una única query. Solicitando en vez de X articulos, X+1, en el pintado, nos aseguraremos de solo pintar los X articulos, pero si el numero de registros recuperado es X+1 , sabremos que tenemos que pintar el link

<?php
$lSQL ='SELECT * FROM articulos ORDER BY FechaPublic DESC LIMIT 11';
$resultado = $mysqli->query($lSQL);
$resultado->data_seek(0);
for ($num_fila = 0; $num_fila<$resultado->num_rows && $num_fila<10;$num_fila++){
  $resultado->data_seek($num_fila);
  $fila=$resultado->fetch_assoc();
  //Codigo de pintado de la pagina linea
}
if($resultado->num_rows>10){
//Cremos el link
}

En el segundo caso, evitamos hacer dos consultaras a la BD, y controlamos el numero de resultados mostrados vía código.

Las consultas a bd en entornos como el del ejemplo php y mysql, suelen ser el mayor lastre. Por lo que trucos como este mejoran considerablemente el rendimiento de nuestra aplicación web.

Añadir Limit en las querys que solo retornan un registro

Otra mejora, bastante simple de implementar es el uso de los limites, en las querys aunque estos parezcan obvios

Por ejemplo la siguiente query :

 SELECT * FROM articulos WHERE Ruta LIKE 'ciudad-romana';

Si la ejecutamos una vez, tarda 0,0039seg en obtener el registro, el campo Ruta es unique, por lo que solo puede retornar un resultado.

Si ejecutamos varias veces esta misma query, podremos ver que el tiempo de respuesta baja, pues mysql ya lo tiene cacheado, pero tras varias ejecuciones podemos ver que no baja de 0,0030seg

Pero simplemente añadiendole un limite de 1 registro, dado que sabemos que no puede retornar más, observaremos que mejoramos su rendimiento bajando a 0.0007 seg

SELECT * FROM articulos WHERE Ruta LIKE 'ciudad-romana' LIMIT 1;

Como vemos, se puede apreciar una mejora sustancial.

Esto se debe a que Mysql, aunque la columna sea unique, sigue buscando en la tabla más coincidencias, aunque ya lo ha encontrado.
Al añadir el limite evitamos que siga escaneando la tabla en busca de resultados una vez encuentre el primero.