martes, 26 de enero de 2016

Aceleramiento de consultas en bases de datos MySQL

Hoy les traigo un pequeño aporte de aceleramiento de consultas en bases de datos MySQL. En realidad recién estoy entrando en este campo de optimización, porque nunca había tenido la necesidad de realizar este tipo de procesos pero siempre hay una primera vez.

Bueno les voy a dar como ejemplo mi caso en un proyecto que he estado trabajando con el lenguaje de programación PHP, tenía los siguientes bucles anidados:

$listaEmpresaPartida = $this->gEmpresaPartida->listarEmpresaPartidaSinDetalle();
for($i = 0; $i < sizeOf($listaEmpresaPartida); $i++) {
        $idEmpresaPartida = $listaEmpresaPartida[$i][0];
        $partida = $listaEmpresaPartida[$i][1];
        $empresa = $listaEmpresaPartida[$i][2];
        $fechaInicio = $listaEmpresaPartida[$i][3];
        $fechaFin = $listaEmpresaPartida[$i][4];
        
        $detalleSinRelacion = $this->gDetalle->listarDetalleSinRelacionPorPartidaEmpresaFechaInicioFechaFin($partida, $empresa, $fechaInicio, $fechaFin);
        for($j = 0; $j < sizeOf($detalleSinRelacion); $j++) {
          $fob = $detalleSinRelacion->getFob();
          $cantidad = $detalleSinRelacion->getCantidad();
          $fecha = $detalleSinRelacion->getFecha();
          $tipo = $detalleSinRelacion->getTipo();
          
          //Esto lo hago para no repetir registros en la base de datos
          if(!$this->gDetalle->existePorIdEmpresaPartidaFechaTipo($idEmpresaPartida, $fob, $cantidad, $fecha, $tipo)) { 

...
...
...

Si se fijan trabajo con clases y siempre obtengo arrays de objetos los cuales recorro con bucles for. Bueno vamos contándoles que había detrás.

Contaba con una base de datos de apenas 10 tablas pero 4 tablas contaban con más de medio millón de registros los cuales tenía que consultar y sacar un reporte que me había solicitado mi cliente en excel.

La configuración de mis 10 tablas al comienzo eran InnoDB y mi motor de BD estaba configurado de forma básica.

El pedazo de código que ven arriba para sacar un reporte en excel demoraba en sacar los datos cerca de 40 a 45 minutos, claro como les recuerdo estaba consultando cerca de 2 millones de datos.

Pasos que he seguido para optimizar

1) Configurar mi motor de base de datos, aumentando cache, utilización de memoria entre otros, busquen en Google y te dan varios ejemplos de como configurar tu servidor MySQL.

2) Las 4 tablas (las que cuentan con una gran cantidad de registros) las he pasado de InnoDB a MyISAM, y las relaciones las trabajo por código.

3) Crear índices de los campos que consulto frecuentemente en las consultas (este paso redujo notablemente el tiempo).

Estimados he logrado que mi algoritmo de 45 minutos aproximadamente se reduzca a 6 minutos aproximadamente.

Espero les sirva estos pequeños consejos, su amigo Carlos Zacarías.