Encuentra la solicitud costosa antes de cambiar la base de datos
Parte de una acción de usuario: carga de categoría, búsqueda de artículo, añadir al carrito o envío de pedido. Captura su ruta, número de consultas, duración en la base de datos, filas devueltas y duración de la petición. Una página lenta también puede esperar a código de aplicación u otra dependencia, así que no diagnostiques solo por el tiempo de carga de la página.
Un plan de consulta es la ruta de la base de datos a través de tablas, índices, joins, ordenaciones y agregaciones. En PostgreSQL, EXPLAIN muestra esa ruta. EXPLAIN ANALYZE ejecuta la sentencia e informa filas y tiempos reales, así que usa una consulta representativa segura. Una gran diferencia entre filas estimadas y reales es motivo para investigar estadísticas o condiciones, no una petición automática de índice.
Vincula una consulta candidata a una ruta y un resultado, para que un informe de panel no supere a un checkout lento.
Registra tiempos antes del cambio y tráfico comparable sin registrar identificadores de clientes, tokens o valores relacionados con tarjetas.
Diseña índices para la ruta de acceso que realmente usas
Un índice es una estructura mantenida que puede ayudar a localizar filas o devolverlas en orden; no es un interruptor universal de velocidad. Empieza por los filtros, claves de join y orden de una consulta importante, y después confirma el índice propuesto en un plan. PostgreSQL documenta que un índice B-tree coincidente puede satisfacer ORDER BY sin una ordenación separada, especialmente con un LIMIT pequeño.
Los índices añaden almacenamiento y trabajo de escritura porque inserciones, actualizaciones y borrados los mantienen. Para una consulta que necesita una gran fracción de una tabla, un escaneo secuencial y una ordenación explícita pueden ser más rápidos. Prueba con datos similares a producción y conserva un índice solo cuando el beneficio justifique su coste.
Usa los filtros reales de la consulta y el ORDER BY, incluyendo un desempate determinista cuando la interfaz necesita un orden estable.
Revisa si un índice se usa y qué cuesta durante las escrituras; reevalúalo a medida que cambian datos y tráfico.
Haz la paginación estable y asequible
La paginación por número de página suele usar LIMIT más OFFSET. Impón siempre un orden predecible. PostgreSQL advierte que sin ORDER BY, LIMIT puede devolver un subconjunto impredecible; distintos valores de LIMIT u OFFSET pueden producir subconjuntos inconsistentes porque el optimizador puede elegir planes diferentes.
Los offsets grandes merecen escrutinio porque las filas omitidas todavía deben calcularse. Para catálogos profundos, historial de pedidos o navegación de archivos, considera la paginación por cursor o keyset: solicita filas después del último valor estable de orden y un desempate único. Define cómo aparecen registros nuevos o borrados antes de cambiar la interfaz.
Devuelve la página más pequeña útil en lugar de un resultado sin acotar.
Decide si la interfaz realmente necesita un total exacto en cada solicitud.
Cachea trabajo de lectura sin servir respuestas incorrectas
El cache reutiliza un resultado previo en lugar de reconstruirlo desde la base de datos. Empieza en la capa HTTP para páginas públicas y repetibles y activos versionados, porque un acierto de caché puede evitar trabajo de aplicación y base de datos. web.dev recomienda caché de larga duración para URLs versionadas; cambiar la URL es el mecanismo práctico de invalidación.
La política de caché es una decisión de corrección. Una caché compartida puede reutilizar una respuesta entre usuarios, así que no compartas salida específica de cuenta, carrito, precio o autorización a menos que esté diseñada y probada para ese ámbito. Cache-Control private restringe la reutilización a la caché del navegador, mientras que no-store indica a las cachés que no la retengan.
Separa salida pública de catálogo o artículo de la salida específica de sesión, ubicación y sensible a permisos.
Define quién puede ver un valor obsoleto, durante cuánto tiempo y la ruta de invalidación o revalidación.
Protege la capacidad de conexiones en vez de simplemente subir el techo
Una conexión es una sesión cliente activa hacia la base de datos. Workers, cron jobs, vistas previas o reintentos pueden agotar los slots incluso cuando consultas individuales parecen aceptables. max_connections de PostgreSQL controla las conexiones concurrentes, se establece al arrancar el servidor y un valor mayor asigna más recursos incluyendo memoria compartida. Subirlo sin un modelo de carga puede desplazar el fallo.
Establece un presupuesto único entre workers web, trabajos en segundo plano, administración y réplicas. Usa pooles acotados donde proceda, preserva margen para recuperación y aplica timeouts para que trabajo varado no espere indefinidamente. Números seguros dependen del motor, memoria, mezcla de consultas y límites del proveedor; confírmalo con el operador.
Incluye procesos web, colas, tareas programadas, migraciones, herramientas de reporting y trabajos de despliegue.
Acota la concurrencia y usa backoff para que una falla no multiplique la demanda de conexiones.
Observa el coste de las consultas con contexto y controles de privacidad
Jerarquiza el trabajo de base de datos por impacto total, no por una muestra lenta. Una consulta moderadamente lenta llamada miles de veces puede importar más que un informe raro. pg_stat_statements de PostgreSQL agrega datos de planificación y ejecución incluyendo llamadas, tiempo total y medio de ejecución, filas y actividad de buffers. Requiere configuración del servidor y un reinicio para añadirse o quitarse; el seguimiento de planificación puede añadir sobrecarga.
Conecta grupos de consultas a ruta, versión de despliegue y ventana temporal. OpenTelemetry aconseja recoger texto de consulta por defecto solo tras sanitizar reemplazando literales, y usar un resumen de baja cardinalidad para agrupar. Esto ayuda a los responsables a ver tendencias sin exportar datos de clientes ni crear una etiqueta por cada valor.
Revisa duración, tiempo total, llamadas, errores, conexiones y filas; cada uno expone un modo de fallo distinto.
Usa consultas parametrizadas y verifica que los literales se eliminan antes de que trazas o logs salgan de la aplicación.
Entrega cambios en la base de datos como trabajo de fiabilidad reversible
Trata un índice, reescritura, política de caché, ajuste de pool o cambio de esquema como un cambio en producción con un responsable, medida de éxito y decisión de reversión. Valida en un entorno representativo, despliega a una porción limitada y vigila el recorrido afectado. Más rápido no es éxito si el cambio devuelve datos erróneos, faltantes, duplicados o desactualizados.
Los cambios de esquema necesitan cuidado porque versiones de la aplicación pueden solaparse. La guía de Google Cloud describe una secuencia de compatibilidad: publica una aplicación que soporte esquema viejo y nuevo, cambia el esquema y luego publica la funcionalidad que lo usa. Esto preserva una ruta de reversión de la aplicación. El bloqueo y el comportamiento de cambio online difieren según el motor y el servicio gestionado; solicita revisión cualificada para sistemas de alto volumen o relacionados con pagos.
Nombra la ruta, señales de rendimiento y corrección, y el umbral que detiene el despliegue.
Verifica rendimiento y corrección en una porción controlada antes de ampliar; practica la ruta de regreso fuera de un incidente.
