Skip to main content

Command Palette

Search for a command to run...

Estrategias de Caching: APEX & Database Cache

Desde Page Cache hasta Server Result Cache: Una Guía Integral para Apps de Alto Rendimiento

Published
8 min read
Estrategias de Caching: APEX & Database Cache

La consulta más rápida es la que nunca ejecutas

🇺🇸 Read in English

Existe una idea equivocada muy común en el desarrollo de bases de datos: "Si es lento, solo agrega un índice."

Aunque indexar es crítico, resuelve un problema de recuperación de almacenamiento, no uno de arquitectura. En aplicaciones APEX de alta concurrencia, el cuello de botella a menudo no es el I/O de disco, sino los ciclos de CPU requeridos para calcular el mismo resultado una y otra vez para miles de usuarios.

Si 500 usuarios solicitan exactamente el mismo "Reporte de Ventas Semanal" en un minuto, ¿por qué estamos ejecutando la consulta de agregación 500 veces?

En el APEX Insights de esta semana, exploramos las Capas de Caching disponibles en el ecosistema Oracle, desde el navegador hasta la función PL/SQL, y cómo usarlas para construir aplicaciones que escalan sin esfuerzo.


El Desafío Arquitectónico

Escalar una aplicación APEX rara vez se trata de agregar más hardware; se trata de reducir el desperdicio. Cada vez que tu aplicación ejecuta lógica que produce el mismo resultado que una ejecución anterior, estás desperdiciando recursos (CPU, contención de Latch, DB Time).

Sin embargo, el caching introduce el problema más notorio en ciencias de la computación: Invalidación de Cache.

El desafío no es solo "almacenar el resultado"; es saber cuándo confiar en él y cuándo descartarlo. Un dashboard mostrando precios de acciones de ayer es inútil (o peligroso). Un dashboard mostrando "Ventas Totales" de ayer podría ser aceptable.

Como arquitectos, debemos definir la Tolerancia de Frescura para cada componente.


Modelos Mentales: Las 3 Capas de Caching

Cuando un usuario ve una página APEX, los datos fluyen a través de múltiples capas. Podemos inyectar caching en puntos distintos:

  1. APEX Page/Region Cache: El HTML renderizado es almacenado. La consulta a base de datos no se ejecuta, y el motor de renderizado de APEX se salta el trabajo. (Lo más rápido para el usuario, lo menos flexible).

  2. Server Result Cache (PL/SQL): La lógica se ejecuta, pero el resultado de la función se almacena en el Shared Pool. La consulta podría correr una vez, pero las llamadas subsecuentes se saltan el cómputo.

  3. Database Cache (Buffer Cache): El mecanismo estándar de Oracle. Los bloques están en memoria, pero la consulta y la lógica aún se ejecutan. (Asumimos que esto siempre está activo).

Nos enfocaremos en los dos primeros, ya que están bajo tu control directo.


Patrones Estratégicos

1. APEX Region Caching (La "Fruta al Alcance de la Mano")

Para contenido estático o reportes pesados que no cambian cada segundo, el Region Caching es poderoso.

  • Mecanismo: APEX almacena el HTML renderizado en una tabla (WWV_FLOW_PAGE_CACHE).

  • Mejor Caso de Uso: Reportes de "Top Vendedores del Mes", listas de navegación o gráficos pesados que se actualizan cada noche.

  • Configuración:

    • Cache: Cached by User o Cached for All Users.

    • Cache Timeout: Por ejemplo, 3600 (1 hora).

Consejo de Consultor: Ten extremo cuidado con "Cached for All Users" si tu consulta incluye :APP_USER o políticas VPD. Podrías mostrar accidentalmente datos privados del Usuario A al Usuario B.

2. PL/SQL Server Result Cache (El "Motor de Escalabilidad")

Esta es la característica más infrautilizada en aplicaciones APEX de alto rendimiento. Permite a una función PL/SQL almacenar su valor de retorno en el Shared Pool de la base de datos. Es cross-session (entre sesiones).

  • Mecanismo: Si funcion(A) retorna B, Oracle recuerda "A -> B". La próxima vez que cualquier sesión llame a funcion(A), retorna B instantáneamente sin ejecutar el cuerpo.

  • Rastreo de Dependencias: Si la función consulta la TABLA_X, y la TABLA_X es actualizada, el cache se invalida automáticamente.

3. Caching de Subconsultas Escalares

Si llamas a una función dentro de una consulta SQL, el cambio de contexto (SQL <-> PL/SQL) mata el rendimiento.

El Enfoque Ingenuo (Lento):

SELECT e.ename,
       get_dept_name(e.deptno) -- ¡Cambio de contexto por fila!
  FROM emp e;

El Enfoque Optimizado: Oracle automáticamente cachea los resultados de subconsultas escalares en memoria por la duración de la ejecución de la consulta. Si get_dept_name(10) es llamada 100 veces, se ejecuta una vez. Esto es automático, pero saber que existe te ayuda a diseñar mejor SQL.


Implementación Técnica

Implementando RESULT_CACHE

Aquí se muestra cómo implementar correctamente una función con result-cache para una búsqueda de configuración.

CREATE OR REPLACE FUNCTION get_system_param (
    p_param_name IN VARCHAR2
) RETURN VARCHAR2
RESULT_CACHE
RELIES_ON (system_parameters) -- Dependencia de tabla
IS
    l_value VARCHAR2(255);
BEGIN
    -- Este cuerpo solo se ejecuta si el resultado NO está en el cache
    SELECT param_value
      INTO l_value
      FROM system_parameters
     WHERE param_name = p_param_name;

    RETURN l_value;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        RETURN NULL;
END;
/

Explicación Clave:

  • RESULT_CACHE: Instruye a Oracle a cachear el resultado.

  • RELIES_ON: Le dice explícitamente a Oracle los cambios de qué tabla deberían limpiar este cache.

La Trampa "Específica de Sesión"

Un error común es cachear datos que dependen del estado de sesión (por ejemplo, V('APP_USER')) dentro de una función RESULT_CACHE sin pasarlo como parámetro.

Código MALO (Riesgo de Seguridad):

CREATE OR REPLACE FUNCTION get_user_role RETURN VARCHAR2
RESULT_CACHE -- ❌ PELIGROSO: ¡Sin dependencia del usuario!
IS
BEGIN
    -- La función no tiene parámetros.
    -- Si el Usuario A la llama, el resultado es "ADMIN".
    -- Si el Usuario B la llama, ¡obtiene "ADMIN" del cache!
    RETURN lookup_role(V('APP_USER'));
END;

Código BUENO:

CREATE OR REPLACE FUNCTION get_user_role(p_username IN VARCHAR2) RETURN VARCHAR2
RESULT_CACHE
IS
BEGIN
    RETURN lookup_role(p_username);
END;

Ahora la llave del cache incluye el nombre de usuario.


Errores Comunes

  1. VPD & Seguridad a Nivel de Fila: Como se demostró arriba, el Result Cache salta la ejecución estándar de SQL. Si tu consulta usa filtrado por SYS_CONTEXT oculto en una vista, el Result Cache podría saltárselo. Siempre pasa el contexto como parámetros.

  2. Tablas de Alta Volatilidad: Si system_parameters cambia cada segundo, tu función RESULT_CACHE pasará más tiempo invalidando y gestionando el overhead que ejecutando. Solo cachea datos que se leen frecuentemente pero se escriben raramente (Read-Mostly).

  3. Contención de Latch: En concurrencia extremadamente alta (miles de ejecuciones/seg), el latch en el Result Cache puede convertirse en un cuello de botella.


Checklist del Consultor

Usa esta Matriz de Decisión de Caching para auditar tu código antes del despliegue a producción.

Escenario / Tipo de Dato

Alcance

Estrategia Recomendada

Configuración Global

Cross-Session

PL/SQL Result Cache

Dashboard Pesado

Por Usuario

APEX Region Cache (Cached by User)

Reportes Públicos

Todos los Usuarios

APEX Region Cache (Cached for All Users)

Datos Transaccionales

Por Usuario

NO CACHE (Consulta Directa)

Descarga la "Matriz de Decisión de Caching APEX" (PDF) completa para el canal de tu equipo o revisiones de código.

📥 Descargar Checklist PDF


Conclusión

El caching no es un "polvo mágico de rendimiento" que esparces sobre código lento. Es una decisión arquitectónica para intercambiar frescura por throughput (capacidad de procesamiento).

En Oracle APEX, comienza optimizando tu SQL (tuning). Luego, mira hacia el Region Caching para dashboards pesados de solo lectura. Finalmente, usa PL/SQL Result Cache para búsquedas de configuración y datos de referencia.

Hecho correctamente, puedes servir a miles de usuarios concurrentes con la huella de hardware de una Raspberry Pi.


Pregunta para la comunidad: ¿Alguna vez tuviste un incidente de "datos obsoletos" debido a caching agresivo? ¿Cómo manejas la invalidación de cache en tus apps? ¡Discutamos en los comentarios!


🚀 Da el Siguiente Paso

  1. Revisa tu app: Identifica cualquier dashboard pesado de lectura y considera aplicar Region Caching.

  2. Experimenta: Crea una función RESULT_CACHE para tu búsqueda de tabla de configuración.

  3. Suscríbete a APEX Insights: Recibe consejos arquitectónicos avanzados directo en tu bandeja de entrada.

  4. Comparte el Conocimiento: ¡Conecta conmigo en LinkedIn para discutir tus desafíos de caching!

☕ Agendar una Llamada
💼 Conectar en LinkedIn
🐦 Seguir en X


Referencias

  1. Oracle Database Docs: PL/SQL Result Cache

  2. Oracle APEX Docs: Managing Page Caching

  3. AskTOM: When to use Result Cache


💖 Apoya mi Trabajo

Si encontraste útil esta entrada de APEX Insights, ¡considera apoyar los esfuerzos open-source de la comunidad APEX!

GitHub Sponsors
Buy Me a Coffee