leanmind logo leanmind text logo

Blog

TDD Avanzado

Las herramientas que se necesitan para aplicar TDD en el mundo real en cualquier proyecto.

No ignores los índices

Por José Luis Rodríguez Alonso

Todos sabemos que para agilizar una consulta SQL podemos usar índices. Un índice ayuda a la base de datos a buscar lo que queremos sin tener que analizar una a una las filas de una tabla. Pero, ¿sabías que hay algunas situaciones en las que el índice se anula sin avisar? Es lo que se conoce como “index obfuscation”, aquí te describo algunos de los casos más comunes:

Caso 1: Filtrar usando funciones

El índice no se tiene en cuenta cuando filtras utilizando una función sobre una columna con índice. Por ejemplo, si tenemos un índice en la columna users.email y queremos hacer una consulta para filtrar por la palabra test, sin tener en cuenta las posibles mayúsculas, podríamos hacer algo como:

1
SELECT name FROM users WHERE LOWER(email) LIKE '%test%';

El problema es que al hacer un LOWER(email), la base de datos ya no puede hacer uso del índice de users.email y tiene que hacer la búsqueda en toda la tabla.

Hay varias soluciones a esto, para este caso en concreto, podríamos utilizar un collation o tipo de dato en la columna afectada que sea case-insensitive. Otra posible solución es crear un índice para nuestro caso particular, un “functional index”:

1
2
CREATE UNIQUE INDEX idx_users_email_lower
ON users (LOWER(email));

Utilizando el EXPLAIN o EXPLAIN ANALYSE en Postgres se ve una mejora considerable:

Caso 2: Filtrar usando operaciones

Otro caso típico es el de tener un índice en una columna y hacer operaciones con esa columna a la hora de filtrar, por ejemplo:

1
SELECT name FROM products WHERE price / 100 > 10;

La base de datos tiene un índice en la columna price pero no en price / 100, por lo que el índice se anula y la base de datos tiene que hacer esa operación con todas las filas. En este caso la solución no sería crear un nuevo índice, sino mover la operación a la derecha:

1
SELECT name FROM products WHERE price > 10 * 100;  -- o: price > 1000 cents

Caso 3: Filtrar usando diferentes tipos

Dependiendo de la base de datos y el lenguaje de programación que utilices, es posible que estés ignorando los índices sin saberlo si utilizas los tipos incorrectos.

Por ejemplo, imagina una tabla de products con un código numérico pero que, por cualquier motivo, se ha decidido definir como VARCHAR en la base de datos. Si en el código de tu aplicación o en la consulta SQL pasas el tipo incorrecto, la base de datos tendrá que hacer una conversión y también ignorará el índice.

1
2
3
4
5
    SELECT name FROM products WHERE code = 123; -- 698ms
    
    vs

    SELECT name FROM products WHERE code = '123'; -- 0.39ms

Todos estos casos son fáciles de pasar por alto durante el desarrollo, sobre todo si trabajamos con bases de datos de prueba con pocos datos.

Siempre que hagas una consulta SQL es recomendable echarle un ojo al “explain plan”, porque quizás la base de datos esté trabajando más de lo necesario.

También es imprescindible contar con una buena capa de observabilidad para detectar estos problemas lo antes posible.

¿Conoces otros casos que puedan afectar a nuestros índices?

Publicado el 15/03/2024 por
José Luis image

José Luis Rodríguez Alonso

¿Quieres más? te invitamos a suscribirte a nuestro boletín para avisarte cada vez que recopilemos contenido de calidad que compartir.

Si disfrutas leyendo nuestro blog, ¿imaginas lo divertido que sería trabajar con nosotros? ¿te gustaría?

Impulsamos el crecimiento profesional de tu equipo de developers