Skip to main content

· 4 min read
Facundo Condal

Hace algunos meses, abordamos con el equipo una historia de usuario en donde nos informaban un lento rendimiento en una vista del sistema. Analizando la situación, verificamos que el problema provenía de una consulta que no tomaba el índice correcto para la petición que se estaba solicitando.

Esta circunstancia me motivó a escribir este artículo, en donde se analizará un caso simple de ejemplo, en el que se requiere crear un índice en una tabla para optimizar una consulta.

El objetivo no es definir qué son los índices o ahondar en sus características, sino analizar cómo enfrentar este tipo de problemas y qué estrategias podemos implementar para solucionarlos.

Tabla

Para ello, vamos a revisar un ejemplo sencillo. Imagínense que tenemos una base de datos MySQL con la siguiente tabla users, donde la misma tiene un millón de registros y necesitamos filtrar todos los usuarios activos creados en los últimos 3 meses, que se hayan registrado mediante su celular y que esté ordenado por apellido y nombre.

Cuando el motor de base de datos ejecuta la consulta, verifica qué índice se ajusta mejor a la petición que estamos realizando. Si no existen índices en la tabla o ninguno se ajusta a nuestra consulta, se realizará un full table scan, que leerá cada uno de los registros aplicando los parámetros de búsqueda que hemos especificado. Esta operación tendrá muy mala performance, por lo que, es necesario analizar qué índice conviene crear para aumentar la velocidad de la consulta.

Algunos pensarán en la idea de crear índices por cada uno de los campos de la tabla, lo cual es un grave error. La creación masiva de índices en una tabla, conlleva efectos adversos:

  • Cada índice ocupa espacio de almacenamiento en nuestra base de datos.
  • La velocidad en las operaciones de insert, update y delete puede verse afectada, ya que los índices de la tabla deben ser actualizados, ante cada una de estas acciones.

Por lo tanto, la primera decisión que debemos tomar es si conviene crear un índice simple o uno compuesto. Los compuestos son útiles cuando tenemos campos que se consultan comúnmente juntos y ambos tienen un alto grado de cardinalidad (a mayor cantidad de valores únicos, mayor cardinalidad).

Si analizamos nuestra tabla y un posible modelo de negocio, podemos suponer que los campos created_at y active podrían aparecer juntos en varias peticiones. Pero si verificamos su cardinalidad, el campo active tiene una muy baja (solo 2 valores posibles toma este campo), lo que hace que la performance de crear un índice único por created_at y crear un índice compuesto por created_at y active sea similar.

Por ende, la mejor decisión para nuestro caso hipotético, es crear un índice simple por el campo created_at.

A continuación, dejo algunas screens de las pruebas realizadas:

Cantidad total de registros en la tabla. Cantidad total de registros en la tabla

Plan de acción del motor de base de datos, donde se especifica que NO se va a utilizar ningún índice en la ejecución de la consulta. Plan de acción del motor de base de datos

La ejecución de la consulta tardó 1118 ms devolviendo 816 registros. Duración consulta

Creación de índice BTree por campo created_at. BTree

Plan de acción del motor de base de datos, donde se especifica que va a utilizar el índice users_created_at_IDX en la ejecución de la consulta. Plan de acción del motor de base de datos

La ejecución de la consulta tardó 74 ms devolviendo 816 registros. Duración consulta

Como podrán observar, aplicando el correcto índice, la consulta se ejecutó 15 veces más rápido. Esto nos da la pauta de la importancia de aplicar índices en nuestras tablas.

Para finalizar, les dejo algunas recomendaciones:

  • No usar índices en tablas con poca cantidad de datos.
  • Tener cuidado con la cantidad de índices que se utilizan en una tabla, ya que esto puede provocar una baja en el rendimiento de las operaciones de creación, modificación y eliminación.
  • Elegir campos que tengan alta cardinalidad.
  • En los índices compuestos, el orden en que se crean las columnas INFLUYE. Estos pueden hacer uso de todas sus columnas o pueden usar solo algunas, pero solo tomando la parte más a la izquierda. Por ejemplo, si tenemos un índice compuesto por las columnas A, B y C, este servirá como índice por: A, A-B y A-B-C.
  • Si se utiliza un índice compuesto, tratar de elegir en primer lugar un valor con mayor cardinalidad.

· 4 min read
Víctor Hugo Ávila

A finales del 2016, junto con dos grandes profesionales y amigos, fundamos Envíame, la plataforma y API multicourier que ayuda al e-Commerce a gestionar sus envíos.

Cada uno de nosotros asumió el rol fundamental más cercano a su experiencia o área de estudio. Lo mío siempre fue el desarrollo y operación de servicios de tecnología, así como el desarrollo de software. Así que sin mucha reflexión, me puse el sobrenombre de CTO de Envíame.

No deja de ser gracioso -y pretencioso- el título de CTO en una StartUp de 5 personas, donde únicamente existían tres personas dedicadas al desarrollo de software, me cuento entre una de ellas. En un contexto como ese, para el equipo DEV, CTO significaba un desarrollador más.

Nuestro micro equipo DEV fue laboratorio para explorar diferentes enfoques respecto del desarrollo de software escalable, además de constatar cómo las dinámicas de comunicación y colaboración definen la arquitectura de un sistema.

En nuestra etapa de MVP operamos como un equipo “fuertemente acoplado” con una única fuente y organización de requerimientos. Fiel a la proposición de la “Ley de Conway”, que señala que la estructura de un sistema de software será congruente con las estructuras sociales que produce el sistema, el resultado que emergió de nuestro trabajo fue un sistema monolítico.

Mientras continuamos desarrollando y perfeccionando nuestro servicio, el mercado del comercio electrónico continuaba creciendo fuertemente. La solución de software que construimos se convertía en un eslabón clave para resolver una serie de problemas activos en la relación entre el e-Commerce y los proveedores de servicios de distribución, por lo que el crecimiento en la base de clientes y transacciones de la plataforma se multiplicó varias veces año tras año. Poniendo a prueba constantemente nuestras habilidades para rediseñar la arquitectura, para implementar tecnología nueva y para mantenernos en una constante reingeniería de software. Así fue como fuimos transitando desde una arquitectura de monolito hacia la construcción de microservicios desacoplados y una arquitectura dirigida por eventos.

Uno de los desafíos más emocionantes de desarrollar software para este mercado es, sin duda alguna, exponer los sistemas que construimos a momentos de alta demanda, como los CyberDay. Es el momento en que los DEV nos ponemos al frente y demostramos que construimos software de calidad.

Siendo un equipo de tres, vivimos varios momentos de peaks de demanda, y al mirar cómo aumentaba abruptamente la exigencia sobre nuestros servicios, era inevitable sentir un nudo en el estómago. En ese momento resultaban irresistibles comentarios como “Hold the door!”, haciendo referencia a la famosa escena de Game Of Thrones.

Grafico

Así transcurrieron un par de años en que me dediqué completamente a escribir código.

Desarrollar software es una de las actividades que más me apasiona, y escribir código me transporta a una dimensión de inmersión analítica, reflexiva y creativa de total desconexión con el entorno físico: Lo que algunos llaman entrar en “La zona”, ese estado mental de total implicación y foco en la tarea que se ejecuta y el éxito de la misma. En un momento como ese mi mejor compañero de viaje es esa playlist de música que le da ritmo a cada pulsación del teclado y los auriculares que me mantienen atrapado y aislado de cualquier estímulo del “mundo real”.

Al escribir código buscando resolver un problema, detectar un bug, optimizar algún proceso o probar alguna tecnología nueva, me desafío a superar un límite, a dar el extra por llegar a la meta, a no desesperar frente a los obstáculos y poner foco en el objetivo, a perfeccionarme en la marcha, a intentar mirar el futuro y anticiparme, a escribir un mapa y notas sobre el que se pueda volver a recorrer el mismo camino y perfeccionar el texto escrito.

Hoy nuestro equipo de DEV continúa creciendo, con varios equipos de desarrollo, incorporando más personas constantemente. Inevitablemente, me he alejado progresivamente del desarrollo de software para poner el foco en la organización de equipos. Hoy el sobrenombre de CTO tiene un poco más de sentido.

Intentar desempeñar varios roles ha impactado necesariamente a la dedicación de mi tiempo al desarrollo de software, convirtiéndome en un impedimento para que el sistema mantenga e incremente el ritmo de evolución. Un momento decisivo e ilustrativo de lo anterior ocurrió cuando uno de mis compañeros DEV originales, durante una reunión de feedback me observó: “Te percibo bien en tu rol de líder, no así en tu rol Dev, principalmente porque estás menos disponible cada vez”.

Guantes

Colgar los guantes del desarrollo ha sido un proceso intenso pero necesario para llevar a Envíame al siguiente nivel.

Toda renuncia conlleva un duelo, pero la otra cara de la moneda se ha pagado con creces. Construir un gran equipo, con una gran cultura y que continúe desarrollando un servicio de excelencia es un desafío enorme y tremendamente motivante.