Subquery Vs. Join – MySQL Tips

Tengo una aplicación web en la cual muestro los datos de las facturas de clientes, junto con el nombre de cliente. Desde un principio observe que la consulta un poco mas de lo normal, asi que me puse a investigar.

Propiedades de las tablas:

La tabla clientes tiene los tipicos campos, los que nos interesan son Id y Nombre, y luego el Id es PrimaryKey, NotNull, AutoIncrement, y tiene 732 registros

La otra tabla es regfacturas, en la cual se registran los datos importantes de las facturas, los campos que nos interesan son el id y el idCliente, el id es PrimaryKey, NotNull, AutoIncrement y el idCliente no esta definido como ForeingKey, luego probaremos a definirlo a ver que resultados nos salen. Esta tabla tiene 4950 registros.

Las dos tablas son InnoDB y como collation utf8, la version del servidor es 5.1.58 y voy a efectuar las consultas en la consola de MySQL.

Nota: Para que los resultados sean efectivos es recomendable efectuar un vaciado de la cache de consultas:


flush query cache;

La consulta original es:


Select r.id as id,r.codigo as codigo,r.fecha as fecha,r.importe as importe ,r.obs_alt as obs_alt,
 c.Nombre as nombre from regfacturas as r join clientes as c on r.id_cliente like c.id order by r.fecha desc

Los resultados de esta consulta fueron: 4945 rows in set (1.71 sec)

Visto estos tiempos, me plantee modificar la consulta y hacerla con subquery

La consulta con subquery es:


Select id, codigo, id_cliente as idCliente,
date_format(fecha,'%d-%m-%Y') as fecha,
importe, obs_alt as observaciones,
(Select Nombre from clientes where id = id_cliente) as cliente
FROM regfacturas order by fecha desc

Los resultados de esta consulta fueron: 4950 rows in set (0.16 sec)

Vistos estos resultados uno dice menuda diferencia entre la subquery y el join, entonces para que usar join, a partir de ahora todo a subquerys. Antes de lanzarnos como locos vamos a afinar un poco mas.

Vamos a probar ahora la consulta con join pero sin la ordenacion de fechas a ver si es eso lo que hace que funcione lenta


Select r.id as id,r.codigo as codigo,r.fecha as fecha,r.importe as importe ,r.obs_alt as obs_alt,
 c.Nombre as nombre from regfacturas as r join clientes as c on r.id_cliente like c.id

Los resultados de esta consulta fueron: 4945 rows in set (1.68 sec)

Parece que sin la ordenacion de fecha ganamos algo de velocidad, aunque el tiempo de respuesta sigue siendo inaceptable

Probemos ahora con la subquery


Select id, codigo, id_cliente as idCliente,
date_format(fecha,'%d-%m-%Y') as fecha,
importe, obs_alt as observaciones,
(Select Nombre from clientes where id = id_cliente) as cliente
FROM regfacturas

Los resultados de esta consulta fueron:  4950 rows in set (0.12 sec)

Con estos resultados vemos que la ordenación tanto en una como en otra tabla tiene un coste de entre 0.03 – 0.04 , y que con esta estructura de tabla es muchisimo mas rapido el uso de subquery que de inner joins

Agregando una ForeingKey

Al ir a agregar una ForeingKey al id_cliente me dio el siguiente error

ERROR 1452: Cannot add or update a child row: a foreign key constraint fails

Googleando descubri que no se podia agregar por que habia registros en la tabla en la cual queria crear la clave foranea que no estaban en la otra tabla.

Para descubir cuales eran estos registro hize la siguiente consulta:


SELECT COUNT( * ) AS cuenta
FROM regfacturas t1
LEFT JOIN clientes t2 ON t1.id_cliente = t2.id
WHERE t2.id IS NULL

El resultado de esta consulta nos dio 5, lo que nos quiere indicar que tenemos 5 campos que estan mal
A continuacion haciendo la siguiente consulta

SELECT * FROM regfacturas t1 LEFT JOIN clientes t2 ON t1.id_cliente = t2.id WHERE t2.id IS NULL

Salieron los campos que nos daban problemas, los borramos, y ya se pudo establecer la FK.
Ahora que ya la tenemos definida vamos a repetir las consultas a ver que sale
La consulta con inner Join dio el siguiente resultado: 4945 rows in set (1.80 sec)
Y la consulta con subquery: 4945 rows in set (0.13 sec)


Con estos resultados podemos decir que en determinados casos es mas rapido usar subquery que inner join, y que establecer foreing keys hace que la consulta se ralentize sobre todo en el caso del uso de inner join

Anuncios

Borrado múltiple – MySQL Tips

Muchas veces nos pondemos encontrar con el caso de tener que borrar un registro de dos tablas. Por ejemplo: Tenemos una tabla pedidos a la cual llamaremos ‘pedidos’ y otra tabla a cual la llamaremos ‘lineasPedido’ pues bien, queremos que si borramos el pedido se borren tambien las lineas de pedido, y todo esto con una sola consulta.

Como campos importantes en este ejemplo vamos a tomar que pedidos tiene un campo id , y lineasPedido tiene aparte del id un campo idPedido que es el que tiene la relacion con la tabla pedidos.

Imaginemos que queremos borrar el pedido 1000, pues vamos ha hacerlo con una sola consulta:


DELETE FROM c, d  USING `pedidos` p, `lineasPedido` l
 WHERE p.id = l.idPedido AND p.id = 1000

Y con esto en una sola consulta borrariamos los datos relacionados de las dos tablas

+ Info http://dev.mysql.com/doc/refman/5.1/en/delete.html

Fullcalendar jQuery Plugin – Tu calendario estilo Google

Buscando por internet una manera rápida de generar un calendario de tareas de una manera sencilla, encontré este plugin el cual me ha sorprendido lo sencillo que es implementarlo
+ Info fullcalendar

Introducción a Git » phpmaster

Buen tutorial sobre el uso de Git

Introduction to Git, Part 1 » phpmaster.

Introduction to Git, Part 2 » phpmaster.

Desktop Wallpaper Calendar: December 2011

Llega diciembre y con el la navidad, te apetece cambiar el fondo de escritorio de tu ordenador y personalizarlo mas con la epoca de la año en la cual estamos, pasate por esta pagina web y descargate el que mas te guste. Yo personalmente cada mes me cambio el fondo de escritorio con uno de los que me proponen. Este diciembre este es mi fondo de escritorio.

 

+ Info: http://www.smashingmagazine.com/2011/11/30/desktop-wallpaper-calendar-december-2011-christmas/

20 Fotos de Star Trails muy Interesantes

20 fotografias para inspiarnos si queremos fotografiar estrellas en movimiento.

+ Info http://www.dzoom.org.es/noticia-9687.html

TipTip jQuery Plugin – Plugin jQuery para crear nuestros ToolTips

Buscando por internet a ver si encontraba con algun plugin sencillo para hacer tooltips di con este el cual me gusto tanto en el resultado como en la facilidad de usarlo.

Primero necesitamos la ultima version de jQuery, la cual la bajamos de la pagina http://jquery.com/ , recomiendo la minified para produccion. Yo en este ejemplo he usado la verison 1.7.1, que era la estable en el momento de escribir esta entrada

Segundo nos lo descargamos de la pagina web de su creador http://code.drewwilson.com/entry/tiptip-jquery-plugin

El archivo comprimido contiene tres ficheros, el jquery.tipTip.js, el jquery.tipTip.minified.js, y tipTip.css. Realmente para nuestra web solo necesitamos el minified y el css el otro es el mismo que el minfied pero sin comprimir.

Agregando los ficheros a nuestra pagina.

Voy a suponer que lo vamos a colgar todo en el mismo directorio, si no seria cambiando la ruta.

Fichero index.html


<!DOCTYPE HTML>
<html lang="es">
<head>
<meta charset=utf-8 />
<link href="tipTip.css" rel="stylesheet" />
<script src="jquery-1.7.1.min.js"></script>
<script src="jquery.tipTip.minified.js"></script>
<title>Probando el TipTip</title>
</head>

Una vez ya tenemos enlazados los ficheros en nuestra cabezera html pasaremos a probar el plugin a ver que tal funciona
Parte del body en el fichero index.html

<body>
<div class='tipTip' title='Hola Mundo!!!!'>Si pasas el raton por encima saludare</div>
<script>
</script>
</body>
</html>

El mensaje que nos mostrara como tooltip es que que esta en la propiedad title.
Ahora insertaremos el script entre las etiquetas script.

$(function(){
 $(".tipTip").tipTip();
});

Y voila ya tenemos habilitado el tooltip

Si quisieramos ubicar el tooltip en algun lugar en particular del texto añadiriamos una de estas clases al tooltip que quisieramos modificar

  • tip_top – El tooltip aparece arriba del elemento.
  • tip_bottom – El tooltip aparece abajo del elemento .
  • tip_left – El tooltip aparece a la izquierda del elemento.
  • tip_right – El tooltip aparece a la derecha del elemento.
  • tip_left_top –  El tooltip aparece a arriba a la izquierda del elemento.
  • tip_left_bottom –  El tooltip aparece abajo a la izquierda del elemento.
  • tip_right_top –  El tooltip aparece arriba a la derecha del elemento.
  • tip_right_bottom –  El tooltip aparece abajo a la derecha del elemento.

TipTip ha sido testeado y funciona con  IE7 & IE8, Firefox, Safari, Opera y Chrome.

+ Info http://code.drewwilson.com/entry/tiptip-jquery-plugin

Anuncios
A %d blogueros les gusta esto: