¿Puedo usar Stored Outlines con una Standard Edition?

desde la versión 10g.

Podría parecer una respuesta evidente o simple, pero no lo es tanto, ya que se trata de una funcionalidad documentada de manera contradictoria por parte de Oracle.

 

Plan Stability vs SQL Plan Management

Hay dos conceptos que tener en cuenta en relación con los Stored Outlines. Plan Stability (pre 11g) y SQL Plan Management o SPM (>= 11g). Stored Outlines es parte de las funcionalidades de Plan Stability, como podemos ver en la doc de Oracle que enlaza Charle’s Hooper en su blog. Plan Stability, en 8i y 9i es una funcionalidad documentada exclusivamente como Enterprise, por lo que no es posible su uso con Standard Edition.

SPM es una evolución de Plan Stability, pero no sustituye a éste, sino que es una nueva funcionalidad con nuevos componentes (como los SQL Baselines) para mejorar a su predecesor, Plan Stability. De este modo, a partir de 11g, tenemos la posibilidad de emplear las dos opciones PS y SPM.

En una BD 12c, en la que coexisten las dos funcionalidades, vemos en una Standard Edition una importante diferencia entre las dos opciones:

select parameter, value
from v$option
where parameter in ('Plan Stability','SQL Plan Management')

PARAMETER	     VALUE
-------------------- -----
Plan Stability	     TRUE
SQL Plan Management  FALSE

Plan Stability está habilitado, pero SPM no. Sabemos que SPM no es usable en SE y, de manera lógica está deshabilitado impidiendo su uso involuntario. De hecho, muchas funcionalidades Enterprise Edition están deshabilitadas en Standard Edition, como Spatial, Partitioning, Parallel Execution o Basic Compression. Pese a eslabón, sabemos que no siempre opciones Oracle habilitadas implican que pueden ser usadas, como ocurre habitualmente (más antes de 11gR2 y SE) con los packs de Diagnostics y Tuning de la BD, o incluso el acceso a la propia AWR que sigue habilitada en SE por defecto aunque los packs EM no lo están.

 

¿Dónde está la confirmación del uso de Stored Outlines?

No conozco un documento en el que se muestre de manera explícita en versiones 10g o posteriores. En la defensa de esta afirmación tenemos:

  • Las versiones 8i y 9i incluyen Plan Stability (Stored Outlines) entre las funcionalidades exclusivas de Enterprise. Esta distinción deja de aparecer en 10g.
  • Con la aparición de SPM, de nuevo la documentación Oracle hace referencia a una funcionalidad exclusiva para la edición Enterprise. Pese a ello, sigue sin haber referencias a limitaciones de licenciamento de los Stored Outlines en Standard Edition. SPM no incluye Stored Outlines, sino que los sustituye.
  • La edición Standard, cuando menos en las versiones 10g en adelante, traen habilitada esta opción por defecto y permite sin problemas el uso de Stored Outlines.
  • Pese a la duda, como partner Oracle escalé la duda internamente, obteniendo como respuesta que sí, que es una opción disponible en Standard Edition no siendo necesaria ninguna licencia adicional. De todos modos, una consulta similar 3 años antes había recibido contestación contraria, pero en aquel caso la respuesta hablaba de manera incorrecta de SPM, cuando Stored Outlines está claramente fuera de ese paquete funcional. Pese a mi insistencia en la pregunta, en esa ocasión la pregunta murió sin respuesta oficial.

Por lo tanto, con estas premisas, incluyendo la confirmación explícita de Oracle, aceptamos Stored Outlines como opción a tener en cuenta para solucionar problemas con Standard Edition.

 

Pero las Stored Outlines están deprecated, ¿por qué usarlas?

Cierto, la versión 11g fue la primera en la que los Stored Outlines pasaron a ser un componente cuya funcionalidad fue sustituída (y ampliada) por una nueva funcionalidad agrupada en el que Oracle nombró SPM (SQL Plan Management). Así, 11g anunció el fin del mantenimiento evolutivo de los Stored Outlines, que pasaron a estar deprecated. Pese a esto, tanto 11g como 12c mantienen funcionalmente estos componentes, y de hecho, la nota MOS habla de ellos como “legacy technique for providing plan stability“.

Aún así, si tu ecosistema es Standard Edition, pronto verás que no existen alternativas para fijar un plan de ejecución, por lo que esta opción se convierte en un auténtico lujo cuando se trata de solucionar problemas de rendimiento en SE, incluso cuando estamos trabajando en una versión 12c. Salvo el empleo de hints, que pasan por la modificación del código de la aplicación, muchas veces algo imposible en el corto plazo, no contamos con otra herramienta que nos permita fijar cómo debe ejecutarse una consulta.

 

Ejemplo de creación de un Stored Outline

Se trata en este caso de un ejemplo en una BD en versión 12.1.0.1 en la que por motivos no completamente identificados (se aplicaron varias soluciones, como la aplicación de un parche específico para un bug identificado en un SR o la deshabilitación de determinadas funcionalidades del optimizador con la supervisión de Soporte Oracle), en determinadas ocasiones, una consulta que dura menos de 5 segundos, pasa a tardar varios minutos tras sufrir un cambio no esperado en el plan. Ante la imposibilidad de identificar el origen del problema, optamos por la creación de un Stored Outline tras haber identificado un plan de ejecución que se muestra válido independientemente de los valores de las bind variables empleadas en múltiples ejecuciones.

Partimos sun SQL con sqlid=81uujczagk9bf. En el entorno disponemos en memoria del cursor correspondiente, del que obtenemos su información.

select sql_id, hash_value, child_number, plan_hash_value, loaded_versions, open_versions, users_opening, users_executing, fetches, executions, loads, parse_calls, invalidations, first_load_time
from v$sql
where sql_id='81uujczagk9bf'  2    3  ;

SQL_ID	      HASH_VALUE CHILD_NUMBER PLAN_HASH_VALUE LOADED_VERSIONS OPEN_VERSIONS USERS_OPENING USERS_EXECUTING    FETCHES EXECUTIONS      LOADS PARSE_CALLS INVALIDATIONS FIRST_LOAD_TIME
------------- ---------- ------------ --------------- --------------- ------------- ------------- --------------- ---------- ---------- ---------- ----------- ------------- ------------------------------
81uujczagk9bf 3573097838	    0	    317020229		    1		  0		0		0	   5	      1 	 5	     1		   2 2017-07-06/10:20:13
81uujczagk9bf 3573097838	    1	   3438832455		    1		  0		0		0	 166	     37 	 5	    33		   3 2017-07-06/10:20:13

Vemos que en el cursor contamos con dos planes. Tras tener monitorizado el comportamiento de las consultas, sabemos que el segundo plan, con 37 ejecuciones, es correcto y la duración de las consultas con este plan son las esperadas. Cuando se produce el incidente, este plan u otro similar es invalidado y se carga en memoria el plan incorrecto. Vamos a crear el Stored Outline para fijar el plan con plan_hash_value 3438832455, que como vemos, es el hijo número número 1 del cursor 3573097838.

begin
 	dbms_outln.create_outline(
		hash_value => '3573097838',
		child_number => 1,
		category => 'default'
	);
end;
/

Lo que acabamos de hacer es invocar al procedimiento dbms_outln.create_online, indicando el SQL para el que fijaremos el plan (empleando el hash_value y no el sql_id), el identificador de hijo del cursor, y con la categoría default , que es la que emplearía el procedimiento por defecto también si no especificamos nada. En este caso no necesitamos hacer ningún tipo de distinción por categoría, por lo que este valor es válido para nosotros. Vemos el nuevo objeto en la BD:

column name format a30
column owner format a15
column category format a10
column version format a10
select name, owner, category, used, enabled, version
from dba_outlines
/

NAME			       OWNER	       CATEGORY   USED	 ENABLED  VERSION
------------------------------ --------------- ---------- ------ -------- ----------
SYS_OUTLINE_17071016074710901  ARUMEL	       default	  UNUSED ENABLED  12.1.0.1.0

Al emplear dbms_outl.create_online para crear el outline a partir de la información en la shared pool, no nos es posible establecer un nombre, obteniendo uno generado de manera automática por el sistema con el formato SYS_OUTLINE_timestamp. Modificamos el nombre para que sea mas descriptivo.

alter outline SYS_OUTLINE_17071016074710901 rename to fixacion_plan_batch_arumel;

Outline altered.


column name format a30
column owner format a15
column category format a10
column version format a10
select name, owner, category, used, enabled, version
from dba_outlines
/

NAME			       OWNER	       CATEGORY   USED	 ENABLED  VERSION
------------------------------ --------------- ---------- ------ -------- ----------
FIXACION_PLAN_BATCH_ARUMEL     MUT_WEB	       default	  UNUSED ENABLED  12.1.0.1.0