Use Result Cache

1. Documentación en Tahiti -> Oracle Database, 11g Release 2 (11.2) -> Masters Book List -> Performance Tuning Guide -> 7 Configuring and Using Memory -> Managing the Server and Client Result Caches

2. La “Result Cache” es una zona de memoria, ya sea en la SGA o en la memoria de la aplicación cliente, que almacena los resultados de una consulta contra la BD o contra un bloque para su reutilización. La “Result Cache” del servidor contiene la caché de resultados de sentencias SQL y la cache de resultados de funciones PL/SQL, que comparten la misma infraestructura.

Ahora vamos a centrar en la “Result Cache” de servidor. Por defecto el sistema está configurado para poder usarla pero sólo a través de un HINT. Vamos a ver un ejemplo de cómo usar la Result Cache con Hints.

-- Activamos la visualización del plan de ejecución
SET AUTOTRACE ON

-- Lanzamos una consulta que utilice la Result Cache (Hint RESULT_CACHE)
SELECT   /*+ RESULT_CACHE */ department_id, AVG(salary)
FROM     hr.employees
GROUP BY department_id;

En el ejemplo anterior utilizamos el hint “RESULT_CACHE” para forzar su utilización. Si nos fijamos en el plan de ejecución, veremos una operación “RESULT CACHE” que nos indica que se utilizará la cache para almacenar el resultado si no lo tenemos cacheado, o para obtener los datos y evitar operaciones I/O innecesarias.

En la siguiente columna a la operación (Name), tenemos el identificador de la caché (por ej. d5k7m95aqfvby4zwga0514u6bb). Éste se corresponde con la columna CACHE_ID de la vista V$RESULT_CACHE_OBJECTS donde se almacena información de los objetos cacheados de la “Result Cache”.

-- Desactivamos la generación del plan de ejecución
SET AUTOTRACE OFF

-- Consultamos la información de la caché relativa a nuestra consulta
SELECT * FROM V$RESULT_CACHE_OBJECTS WHERE CACHE_ID='d5k7m95aqfvby4zwga0514u6bb';

3. Si no queremos utilizar el hint para activar la caché de resultados, podemos modificar los parámetros de la base de datos para forzar que toda consulta acceda por esta caché en primer lugar.

-- Forzamos la utilización de la caché de resultados para todas las consultas
-- El valor por defecto es 'MANUAL'
ALTER SYSTEM SET RESULT_CACHE_MODE='FORCE' SCOPE=BOTH;

-- Validamos que está en efecto lanzando la misma consulta que antes sin el Hint
-- Activamos la visualización del plan de ejecución
SET AUTOTRACE ON

-- Veremos que aunque no hayamos usado el Hint, sigue apareciendo la operación "RESULT CACHE"
SELECT   department_id, AVG(salary)
FROM     hr.employees
GROUP BY department_id;

Si tenemos activado el parámetro RESULT_CACHE_MODE y queremos que algunas consultas no utilicen la caché podemos usar el parámetro NO_RESULT_CACHE.

-- Lanzamos una consulta que evite la Result Cache (Hint NO_RESULT_CACHE)
-- Veremos que aunque no hayamos usado el Hint, sigue apareciendo la operación "RESULT CACHE"
SELECT   /*+ NO_RESULT_CACHE */ department_id, AVG(salary)
FROM     hr.employees
GROUP BY department_id;

4. Me gustaría repasar el resto de parámetros que afecta a la caché de resultados.

El parámetro RESULT_CACHE_MAX_SIZE fija la memoria destinada a la caché. Si fijamos este valor 0, deshabilitamos la caché. Como estamos usando AMM (parámetro MEMORY_TARGET) el valor por defecto para RESULT_CACHE_MAX_SIZE es el 0.25% de MEMORY_TARGET. En mi caso RESULT_CACHE_MAX_RESULT = MEMORY_TARGET * 0.25% = 1012MB * 0.0025 = 2.5MB.

El parámetro RESULT_CACHE_MAX_RESULT específica el porcentaje máximo que se permite usar de la caché de resultados para un sólo resultado. Por defecto es el 5%.

El parámetro RESULT_CACHE_REMOTE_EXPIRATION específica el tiempo de expiración para un resultado que depende de objetos en una BD remota. Por defecto es 0 minutos y en principio es aconsejable dejarlo asi.

5. Cuando creamos una tabla, podemos especificar que se cacheen los resultados de las consultas que acceden a ella.

-- Creamos una tabla empleados con la claúsula RESULT_CACHE
-- Fijaos que creamos la tabla en el esquema SCOTT
-- Los objetos de SYS/SYSTEM no pueden utilizar la RESULT CACHE
CREATE TABLE SCOTT.CACHED_EMP RESULT_CACHE (MODE FORCE) AS SELECT * FROM HR.EMPLOYEES;

-- Vemos como revisar la configuración de este tipo de tablas
SELECT TABLE_NAME, RESULT_CACHE FROM DBA_TABLES WHERE TABLE_NAME='CACHED_EMP';

-- Podemos desactivarlo y activarlo con ALTER TABLE
ALTER TABLE SCOTT.CACHED_EMP RESULT_CACHE (MODE DEFAULT);

6. Ya hemos visto que podemos obtener cierta información de la caché de resultados accediendo a la vista V$RESULT_CACHE_OBJECTS, pero también podemos usar el paquete DBMS_RESULT_CACHE para obtener información del uso que se le está dando.

-- Lanzamos el Report de utilización detalle de la "Result Cache"
SET SERVEROUTPUT ON
EXEC DBMS_RESULT_CACHE.MEMORY_REPORT(TRUE);

-- Otro método útil del paquete es "FLUSH" para limpiar la caché
-- Limpiamos la caché
EXEC DBMS_RESULT_CACHE.FLUSH();

-- Comprobamos con otro informe en qué situación queda
EXEC DBMS_RESULT_CACHE.MEMORY_REPORT(TRUE);

Más información se puede obtener de las siguientes vistas:

· V$RESULT_CACHE_STATISTICS
· V$RESULT_CACHE_MEMORY
· V$RESULT_CACHE_OBJECTS
· V$RESULT_CACHE_DEPENDENCY
· CLIENT_RESULT_CACHE_STATS$
· DBA_TABLES, USER_TABLES, ALL_TABLES (columan RESULT_CACHE)

7. La caché de resultado de cliente es diferente a la del servidor, y está ubicado en la memoria del cliente (como es de suponer), no en la de la base de datos. Normalmente esta cache se utiliza cuando se usa un driver OCI. No vamos a ver la parte de configuración del cliente, porque depende de la aplicación, pero a nivel de BD se controla con 3 parámetros:

El parámetro CLIENT_RESULT_CACHE_SIZE especifica el tamaño máximo de la “Result Cache” para cada proceso cliente. Para habilitarlo, debemos fijarlo a 32K o superior. Un valor por debajo de 32768 bytes o incluso 0, deshabilita la “Rsult Cache” cliente.

El siguiente parámetro, CLIENT_RESULT_CACHE_LAG, específica el lag permitido de desincronización entre el cliente OCI y la BD. Cuando se supera esta límite, el cliente OCI vuelve a consultar la BD para sincronizar la datos.

La “Result Cache” es una funcionalidad nueva de la versión 11g, así que para poder usarla necesitamos que el parámetro COMPATIBLE sea como mínimo 11.0.0.0. Para poder usar la caché de cliente en vistas, este parámetro debe ser como mínimo 11.2.0.0.0.

-- Comprobamos que podemos usar la Result Cache
-- La BD debería tener un valor de COMPATIBLE = 11.2.0.0.0
SHOW PARAMETER COMPATIBLE

-- Activamos la cache de cliente de la funcionalidad "Result Cache" (debe ser mayor a 32K)
ALTER SYSTEM SET CLIENT_RESULT_CACHE_SIZE=64K SCOPE=SPFILE;

-- Reiniciamos la BD ya que se trata de un parámetro estático
SHUTDOWN IMMEDIATE
STARTUP

-- Comprobamos tras el reinicio que está habilitado
SHOW PARAMETER CLIENT_RESULT_CACHE_SIZE