Como bien dice un desarrollador no tiene que ser diseñador pero ahora también hay otra, la cual es, un programador tiene que ser un DBA, si bien a veces (muchas muchas) la misma persona es diseñador, programador y DBA, es por ello que por mas que nos esmeremos en optimizar código de poco servirá si no hacemos lo mismo con nuestras consultas.
A continuación veremos algunos ejemplos sobre como optimizar consultas si bien para comprenden el rendimiento y tener una mejor es necesario conocer el tamaño de la BD y de los registros, lamentablemente no los tenemos pero espero que viendo las consultas nos podamos dar una idea con las nuestras.
Estas consultas fueron obtenidas de un sitio web, en la cual ofrecen diferentes servicios, este es el link, entre ello la optimización de consultas.
Original – Tiempo medio de ejecución: 0,99 segundos |
Optimizada – Tiempo medio de ejecución: 0,07 segundos |
SELECT id_usuario, login, nombre, apellido, sexo, img_fichero, img_updatefecha, id_pais, id_lugar, tot_contactos FROM USUARIOS WHERE baja=0 AND (id_usuario IN (SELECT id_agregado FROM CONTACTOS WHERE id_agregante=1518 AND activo=1) OR id_usuario IN (SELECT id_agregante FROM CONTACTOS WHERE id_agregado=1518 AND activo=1 )) ORDER BY fecha_ultimo_post DESC |
(SELECT USUARIOS.id_usuario, login, nombre, apellido, sexo, img_fichero, img_updatefecha, id_pais, id_lugar, tot_contactos, USUARIOS.fecha_ultimo_post FROM USUARIOS JOIN CONTACTOS ON USUARIOS.id_usuario=CONTACTOS.id_agregado WHERE USUARIOS.baja=0 AND CONTACTOS.id_agregante=1518 AND CONTACTOS.activo=1 ) UNION DISTINCT ( SELECT USUARIOS.id_usuario, login, nombre, apellido, sexo, img_fichero, img_updatefecha, id_pais, id_lugar, tot_contactos, USUARIOS.fecha_ultimo_post FROM USUARIOS JOIN CONTACTOS ON USUARIOS.id_usuario=CONTACTOS.id_agregante WHERE USUARIOS.baja=0 AND CONTACTOS.id_agregado=1518 AND CONTACTOS.activo=1 ) ORDER BY fecha_ultimo_post desc; |
Original – Tiempo medio de ejecución: 1,03 segundos |
Optimizada – Tiempo medio de ejecución: 0,03 segundos |
SELECT p.* FROM payment p WHERE p.payment_date = (SELECT MAX(payment_date) FROM payment WHERE customer_id=p.customer_id ) |
SELECT p.* FROM ( SELECT customer_id, MAX(payment_date) as last_order FROM payment GROUP BY customer_id ) AS last_orders INNER JOIN payment p ON p.customer_id = last_orders.customer_id AND p.payment_date = last_orders.last_order |
Original – Consulta no cacheable |
Optimizada – Consulta cacheable |
SELECT * FROM Orders WHERE TO_DAYS(CURRENT_DATE()) – TO_DAYS(order_created) <= 7 |
SELECT order_id, customer_id, order_total, order_created FROM Orders WHERE order_created >= '2013-02-01' - INTERVAL 7 DAY |
Original – Tiempo medio de ejecución: 2,21 segundos |
Optimizada – Tiempo medio de ejecución: 0,20 segundos |
SELECT id_post, id_usuario, id_tipo_envio_post, texto, tipo, num_comentarios, fecha_publicacion, priv, vidupl_file, vidupl_img, vidmov_file, vidmov_img, vidcam_file, vidcam_img, vid_id_youtube, vid_tit_youtube, vid_thumb_youtube, vid_time_youtube, mus_id_youtube, mus_tit_youtube, mus_time_youtube, img_fichero, link_tit, link_url, link_texto, link_img, evento_tit, evento_categoria, evento_tipo, evento_fecha_inicio, evento_fecha_fin, evento_telefono_contacto, evento_email, evento_pagina_web, evento_img_site, evento_img_site_size, map_direccion, evento_cancelado,map_latitud, map_longitud, map_zoom, map_id_pais FROM POSTS WHERE (id_usuario=31436 OR id_usuario in (SELECT id_agregado FROM CONTACTOS WHERE id_agregante=31436 and activo=1) OR id_usuario in (SELECT id_agregante FROM CONTACTOS WHERE id_agregado=31436 and activo=1) ) AND (priv=0 or priv=1) AND eliminado=0 AND eliminado_baja=0 AND es_spam=0 ORDER BY id_post DESC |
(SELECT p.id_post, p.id_usuario, p.id_tipo_envio_post, p.texto, p.tipo, p.num_comentarios, p.fecha_publicacion, p.priv, p.vidupl_file, p.vidupl_img, p.vidmov_file, p.vidmov_img, p.vidcam_file, p.vidcam_img, p.vid_id_youtube, p.vid_tit_youtube, p.vid_thumb_youtube, p.vid_time_youtube, p.mus_id_youtube, p.mus_tit_youtube, p.mus_time_youtube, p.img_fichero, p.link_tit, p.link_url, p.link_texto, p.link_img, p.evento_tit, p.evento_categoria, p.evento_tipo, p.evento_fecha_inicio, p.evento_fecha_fin, p.evento_telefono_contacto, p.evento_email, p.evento_pagina_web, p.evento_img_site, p.evento_img_site_size, p.map_direccion, p.evento_cancelado, p.map_latitud, p.map_longitud, p.map_zoom, p.map_id_pais FROM POSTS p JOIN CONTACTOS c ON p.id_usuario=c.id_agregado WHERE (p.priv=0 OR p.priv=1) AND p.eliminado=0 AND p.eliminado_baja=0 AND p.es_spam=0 AND c.id_agregante=31436 AND c.activo=1 ) UNION DISTINCT (SELECT p.id_post, p.id_usuario, p.id_tipo_envio_post, p.texto, p.tipo, p.num_comentarios, p.fecha_publicacion, p.priv, p.vidupl_file, p.vidupl_img, p.vidmov_file, p.vidmov_img, p.vidcam_file, p.vidcam_img, p.vid_id_youtube, p.vid_tit_youtube, p.vid_thumb_youtube, p.vid_time_youtube, p.mus_id_youtube, p.mus_tit_youtube, p.mus_time_youtube, p.img_fichero, p.link_tit, p.link_url, p.link_texto, p.link_img, p.evento_tit, p.evento_categoria, p.evento_tipo, p.evento_fecha_inicio, p.evento_fecha_fin, p.evento_telefono_contacto, p.evento_email, p.evento_pagina_web, p.evento_img_site, p.evento_img_site_size, p.map_direccion, p.evento_cancelado, p.map_latitud, p.map_longitud, p.map_zoom, p.map_id_pais FROM POSTS p JOIN CONTACTOS c ON p.id_usuario=c.id_agregante WHERE (p.priv=0 OR p.priv=1) AND p.eliminado=0 AND p.eliminado_baja=0 AND p.es_spam=0 AND c.id_agregado=31436 AND c.activo=1 ) UNION DISTINCT (SELECT p.id_post, p.id_usuario, p.id_tipo_envio_post, p.texto, p.tipo, p.num_comentarios, p.fecha_publicacion, p.priv, p.vidupl_file, p.vidupl_img, p.vidmov_file, p.vidmov_img, p.vidcam_file, p.vidcam_img, p.vid_id_youtube, p.vid_tit_youtube, p.vid_thumb_youtube, p.vid_time_youtube, p.mus_id_youtube, p.mus_tit_youtube, p.mus_time_youtube, p.img_fichero, p.link_tit, p.link_url, p.link_texto, p.link_img, p.evento_tit, p.evento_categoria, p.evento_tipo, p.evento_fecha_inicio, p.evento_fecha_fin, p.evento_telefono_contacto, p.evento_email, p.evento_pagina_web, p.evento_img_site, p.evento_img_site_size, p.map_direccion, p.evento_cancelado, p.map_latitud, p.map_longitud, p.map_zoom, p.map_id_pais FROM POSTS p WHERE p.id_usuario=31436 AND (p.priv=0 OR p.priv=1) AND p.eliminado=0 AND p.eliminado_baja=0 AND p.es_spam=0 ) ORDER BY id_post DESC |
Espero les halla servido de algo.
No le veo como optimización, es mas bien hacer las cosas bien.
Faltan cosas como normalizar y crear índices en las tablas, asignar tipos de datos según la aplicación, cachear información, particionar tablas, usar el motor correcto, implementas atajos para escenarios comunes, etc.
Aprendiendo lo básico de SQL se resuelven ocurrencias catastróficas como paréntesis innecesarios en consultas y las subselecciones.
Pues es hacer las cosas bien y en cierta manera se esta optimisando, ya que las consultas son un poco mas rápido. pero cierto hay que conocer SQL para para que el codigo optimizado o rapido valga la pena