Cómo optimizar consultas SQL para acelerar tus aplicaciones

Cuando hablamos de rendimiento de bases de datos, muchas veces pensamos en hardware costoso, cachés distribuidos o soluciones complicadas. Pero la verdad es que, a veces, una pequeña línea bien pensada puede marcar toda la diferencia.

Quiero compartirte una experiencia de cómo una API aparentemente sencilla empezó a hacerse lenta y cómo puedes optimizar el rendimiento aplicando uno de los patrones más infravalorados de SQL.

El problema: paginación OFFSET, el enemigo silencioso

Todo empezó con una API de historial de transacciones de usuario, con paginación estándar. Durante meses funcionó como un reloj: respuesta en 200 ms. Pero a medida que la tabla creció, cada consulta comenzó a tardar más… 1 segundo, 2 segundos, hasta más de 3 segundos.

La consulta original se veía más o menos así:

A simple vista, nada raro. El problema era el OFFSET, para llegar a la “página 500”, la base de datos escanea 10.020 filas, descarta 10.000 y devuelve solo 20. Este descarte se repite cada vez, matando el rendimiento a medida que crece la tabla.

La solución: keyset pagination (seek method)

El cambio clave fue reemplazar OFFSET por keyset pagination (también conocida como paginación por cursor o seek method). La idea es sencilla, en lugar de decir “salta 10.000 filas”, dices “devuélveme las 20 siguientes a partir de esta marca”.

De repente, la consulta pasó de 3 segundos a 300 ms. Sin nuevos servidores, sin añadir caché externa. Solo SQL más inteligente.

Pequeños detalles que importan

Duplicados en timestamps:

Nos encontramos con otro problema: varias transacciones podían compartir exactamente la misma fecha y hora (created_at), lo que provocaba resultados duplicados o saltados. La solución fue usar un tie-breaker, como el ID:

Otros trucos que debes tener en cuenta

Índices compuestos bien elegidos: Siempre revisa que tus índices cubran las columnas de filtrado y ordenamiento.
Evita SELECT * : Selecciona solo las columnas necesarias. Esto reduce E/S, uso de CPU y ancho de banda.
Usa EXPLAIN y ANALYZE: Antes de optimizar, entiende qué hace tu consulta realmente.
Vistas materializadas para informes: Para dashboards de análisis, considera usar vistas materializadas actualizadas periódicamente, lo que permite servir datos precalculados de forma eficiente.
Particiona tablas grandes: Divide tablas por fecha o regiones para acelerar búsquedas.

Resultados reales

Estrategia

Tiempo promedio

OFFSET 10k

~3,000 ms

OFFSET + índice

~1,500 ms

Keyset/Seek

~300 ms

Keyset + Cursor

~320 ms

Vista materializada

~50–100 ms

Conclusión

Optimizar SQL no siempre requiere reinventar toda tu infraestructura. A veces, basta entender cómo funciona realmente la base de datos y ajustar tu forma de paginar o filtrar datos.

Si tu aplicación usa OFFSET para paginación y empieza a sufrir con grandes volúmenes de datos, dale una oportunidad al keyset pagination. Es una de esas mejoras pequeñas que te recuerdan por qué escribir buen SQL sigue siendo una de las habilidades más rentables.