Está en la página 1de 29

Introducción al optimizador ............................................................................................ ...

2
¿Qué es el Optimizador? .............................................................................. ................2
Planes de ejecución ............................................................................................... .......3
Etapas del Plan de Ejecución .............................................................. .........................3
El comando EXPLAIN PLAN.......................................................... ...............................3
Tipos de Optimización ................................................................... ...............................3
Operaciones del optimizador................................................................................... ..........4
Evaluación de Expresiones, Condiciones y Constantes ...............................................4
Transformación de sentencias .................................................................... ..................5
Métodos de combinación de tablas ........................................................................... ....6
Optimización de Sentencias en 'Estrella' ........................................... ...........................7
Cómo especificar el tipo de optimización .......................................................................... 7
Optimización basada en costes................................................................................... ......8
Objetivo de la estimación basada en costes.................................................. ................8
Estadísticas para la estimación basada en Costes .......................................................... .9
Características disponibles con la Optimización Basada en Costes.......................... ......10
Recogida de estadísticas..................................................................... ...........................10
Comando ANALYZE .............................................................................................. ......11
Paquete DBMS_STATS ................................................................. .............................11
Histogramas .............................................................................................................. ..12
Caminos de acceso a los datos................................................................................. ......13
Plan de ejecución............................................................................................ ................14
Definición de la tabla PLAN_TABLE.................................................. ..........................15
Operaciones y Opciones de la tabla PLAN_TABLE.................................... .................15
Comando EXPLAIN PLAN .............................................................................. ............17
Optimización basada en Reglas......................................................................... .............18
Introducción a la Optimización de Reglas..................................................... ...............18
Caminos de acceso a los datos............................................................... ....................18
Ajuste de Sentencias SQL. Traza SQL y utilidad TKPROF ............................................ .19
Activar los Parámetros de Inicialización............................................................... ........19
Activar la traza............................................................................................. ................20
Formateo de la traza con TKPROF....................................................................... .......20
Interpretar el fichero de salida..................................................................................... .21
Estadísticas Tabulares................................................................................ .................21
Almacenar estadísticas en la Base de Datos.................................................... ...........22
La característica AUTOTRACE de SQL*PLUS ........................................................ .......23
Ajuste manual de sentencias: Los HINTS ............................................ ..........................23
Propósito de los Hints.................................................................................... ..............23
Comentarios para decidir el método de Optimización........................................ ..........24
Comentarios para decidir el método de Acceso............................................... ............24
Comentarios para decidir el orden de combinación................................ .....................24
Comentarios para decidir el método de combinación...................... ............................25
Comentarios para ejecución en paralelo.............................................................. ........25
Comentarios adicionales.......................................................................................... ....25
Vistas Materializadas .................................................................................................... ..25
Introducción............................................................................................. ....................25
Creación de vistas materializadas.................................................. .............................26
Refresco de vistas materializadas.................................................. .............................26
Reescritura de Consultas......................................................................................... ....26
Estabilidad de Planes.......................................................................................... ............28
Creación de Outlines para Estabilidad de Planes.................................... ....................28
Uso de Outlines con la Optimización basada en Costes........................................ ......29

Optimizacion de Oracle SQL Javier Navarro Grau Página 1 de 29


Introducción al optimizador

¿Qué es el Optimizador?

La base de datos Oracle utiliza la siguiente arquitectura para el procesamiento de


las sentencias SQL que recibe por parte de los usuarios.

Figura 1. Arquitectura de procesamiento SQL de Oracle

Sus principales componentes son :

• El parser, o intérprete, que traduce las sentencias SQL, realizando el Análisis


Sintáctico (comprueba la corrección sintáctica de las instrucciones SQL) y
Semántico (verifica que los objetos utilizados y sus atributos existen y son
correctos), a la representación interna utilizada por Oracle.
• El optimizador, que utiliza reglas internas y estadísticas de coste para
determinar la forma más eficiente de producir los resultados de la sentencia. La
salida del optimizador es un plan óptimo de ejecución.
• El generador de fuentes de registros, que recibe el plan óptimo desarrollado
por el optimizador, y genera el plan de ejecución : una sucesión de fuentes de
registros estructurados en forma de árbol.
• El motor de ejecución de SQL, que recibe el plan de ejecución y lo ejecuta,
extrayendo registros de cada una de las fuentes indicadas, y combinando estos
registros, hasta obtener el resultado de la sentencia.

Para cada instrucción SQL ejecutada por Oracle, el optimizador puede realizar
varias de las siguientes tareas :

1. Evaluación de expresiones y condiciones : Se evalúan expresiones y


condiciones que contengan constantes de la forma más amplia posible

Optimizacion de Oracle SQL Javier Navarro Grau Página 2 de 29


2. Transformación de Instrucciones : Para instrucciones complejas que
contengan, por ejemplo, consultas o subconsultas relacionadas, el optimizador
podría transformar la sentencia original en una sentencia con un join
equivalente.

3. Elección de caminos de acceso : Para cada tabla accedida por la instrucción,


el optimizador elige uno o más de los caminos de acceso disponibles para
obtener los datos de la tabla.

4. Elección de orden para combinaciones (joins) : Para cada instrucción de


combinación entre más de dos tablas, el optimizador elige qué par de tablas se
unen primero, y qué tabla es combinada con el resultado, y así sucesivamente.

5. Elección de métodos de combinación (join) : Para cada combinación, el


optimizador escoge el método idóneo a usar.

Planes de ejecución

Para ejecutar una sentencia SQL, Oracle puede necesitar muchos pasos. En cada
uno de estos pasos, o bien se recuperan registros de datos de la base de datos, o bien se
prepara a aquélla de alguna manera para que el usuario obtenga la salida de su
instrucción. La combinación de pasos que Oracle usa para ejecutar una instrucción es lo
que se denomina Plan de Ejecución. Un plan de Ejecución incluye:

• Una vía de acceso para cada tabla a la que accede la instrucción.


• El orden de la combinación de las tablas, con el apropiado método de
combinación.

Etapas del Plan de Ejecución

Cada etapa del Plan de ejecución devuelve un grupo de registros que o bien son
usados por el siguiente paso, o en él ultimo paso, son devueltos al usuario o aplicación
liberando la instrucción SQL. El grupo de registros devueltos por un paso es conocido
como row set, o conjunto de registros. El origen de estos registros puede ser, o bien, la
recuperación desde un determinado objeto de la base de datos, o bien la combinación de
los row sets obtenidos de los pasos anteriores en el plan de ejecución.

El plan de ejecución forma un árbol. Para procesarlo, el gestor de base de datos


ejecuta en primer lugar los pasos correspondientes a las hojas del árbol. Los registros
obtenidos se convierten en fuentes de los pasos padre de estos. Después Oracle realiza
estos pasos padre, y así sucesivamente hasta llegar a la raíz del árbol.

El comando EXPLAIN PLAN

El comando EXPLAIN PLAN permite obtener, en forma de tabla, el plan de


ejecución elegido por el optimizador de Oracle para la instrucción SELECT, UPDATE,
INSERT y DELETE que se le indique.

Tipos de Optimización

Optimizacion de Oracle SQL Javier Navarro Grau Página 3 de 29


El gestor de base de datos Oracle, en sus versiones actuales, tiene dos métodos de
optimización: el Optimizador Basado en Reglas (RBO ó Rule Based Optimizer) y el
Optimizador Basado en Costes (CBO ó Cost Based Optimizer) :

• El optimizador basado en reglas, que ha sido el principal método de


optimización de Oracle hasta que el optimizador basado en costes, introducido
en la versión 7, ha ido ganando en prestaciones. Se basa en reglas obtenidas
heurísticamente por Oracle, en base a la experiencia con sucesivas versiones.
• El optimizador basado en costes, que tiene en cuenta el estado de la base de
datos en el momento de la ejecución de la sentencia, para determinar cuál de
los planes de ejecución es más eficiente. También tiene en cuenta los hints,
sugerencias de optimización colocadas como comentarios en la instrucción SQL
por el programador.

Operaciones del optimizador

Evaluación de Expresiones, Condiciones y Constantes

El optimizador realiza una serie de operaciones con la sentencia, transformándola y


normalizándola, de manera que sea más fácil obtener un plan de ejecución óptimo. Entre
estas operaciones está la evaluación de las expresiones, de las condiciones y de las
constantes.

• Las expresiones constantes son evaluadas durante la optimización, de manera


que no se tengan que evaluar una y otra vez durante la ejecución. Esta
evaluación se limita a los términos de las condiciones, no a las propias
condiciones. Por tanto, siempre es preferible pasar todas las expresiones
constantes a un lado de la condición, para que Oracle las evalúe juntas.

• Las condiciones IN pueden ser traducidas a múltiples condiciones de igualdad,


separadas por operadores OR.

• Los operadores NOT pueden ser eliminados, mediante la transformación de la


condición que se niega. Esta transformación puede implicar la introducción de
nuevas condiciones con operadores NOT, que podrían ser optimizadas a su
vez.

• Las condiciones que usan el operador BETWEEN son substituidas por


condiciones equivalentes que usen los operadores de comparación >= y <=.

• Los operadores ANY y SOME seguidos de una lista de valores, se traducen a


condiciones individuales, separadas por operadores OR. Si van seguidos de
una subconsulta, se traducen a una condición EXISTS, con una condición más
en la subconsulta.

• Los operadores ALL seguidos de una lista de valores, se traducen a condiciones


individuales separadas por operadores AND. Si van seguidos de una
subconsulta, se traducen a operadores ANY, con una condición contraria en la
subconsulta. El operador ANY obtenido podrá ser transformado, a su vez.

Optimizacion de Oracle SQL Javier Navarro Grau Página 4 de 29


• La optimización de subexpresiones comunes, busca partes comunes en
condiciones separadas por operadores OR, de manera que puedan ser
eliminadas de estas condiciones, y ejecutadas una única vez.

• El optimizador puede tener en cuenta las funciones determinísticas (funciones


que devuelven siempre el mismo resultado para los mismos parámetros de
entrada) para evaluarlas en tiempo de optimización, o utilizar resultados
almacenados en tiempo de ejecución. El programador puede usar la palabra
clave DETERMINISTIC para indicar que una de las funciones que define es
determinística.

• El optimizador basado en costes, además, puede introducir nuevas condiciones


obtenidas por transitividad, a partir de otras condiciones ya existentes en la
sentencia.

Transformación de sentencias

SQL es un lenguaje bastante flexible, se pueden utilizar diferentes caminos para


lograr el mismo objetivo. Muchas veces, el optimizador transformará una sentencia en otra
que obtenga el mismo resultado, pero sea más eficiente. Algunas de las transformaciones
que aplica el optimizador son :

• Consultas con operadores OR, en múltiples consultas unidas por UNION :


si el optimizador encuentra que separar la sentencia inicial en múltiples
sentencias, cada una con una de las condiciones separadas por OR, y después
unirlas mediante el operador UNION, es más eficiente que la primera opción.

• Subconsultas, en combinaciones (joins) : si la transformación de la


subconsulta en una combinación con la consulta principal asegura el mismo
resultado que la consulta inicial, el optimizador puede transformarla y proceder
a la optimización de la nueva consulta obtenida.

• Combinaciones con vistas, en combinaciones con sentencias : si se puede


substituir la referencia a una vista por la referencia a su sentencia de creación, e
intentar la optimización de la nueva sentencia obtenida. No se podrá realizar
esta substitución si la vista contiene, en su sentencia de creación, operadores
UNION, INTERSECT, MINUS, CONNECT BY, la seudocolumna ROWNUM, o
las funciones de grupo AVG, COUNT, MAX, MIN y SUM.

• Combinaciones con vistas complejas : si se ha activado la combinación de


vistas complejas, Oracle puede intentar la tranformación de vistas con funciones
de grupo y cláusulas GROUP BY.

• Expansión de predicados : si una vista no es combinable con la sentencia que


hace referencia a ella, se puede transformar su sentencia de creación, mediante
la introducción de las condiciones de la sentencia inicial correspondientes a la
vista, dentro de la sentencia de creación.

• Consultas compuestas, en consultas simples unidas por operadores : el


plan de ejecución de una consulta compuesta, se transforma en planes de

Optimizacion de Oracle SQL Javier Navarro Grau Página 5 de 29


ejecución paralelos para cada una de las subconsultas, unidos por los
correspondientes operadores (UNION, INTERSECT, MINUS).

Métodos de combinación de tablas

Los joins son sentencias que devuelven datos de más de una tabla (o de una única
tabla referenciada varias veces). Un join esta caracterizado por múltiples tablas en la
cláusula FROM y la relación entre estas tablas es definida a través de la condición
WHERE. El optimizador cuenta con varios métodos para realizar combinaciones entre
tablas, y debe elegir entre ellos el más eficiente. Entre los principales métodos de join
están :

• Bucles Anidados (Nested Loop Joins) : el optimizador utiliza este método con
conjuntos de datos pequeños, y en el caso de que la condición de join sea un
camino de acceso eficiente para la tabla “interior”. El optimizador determina cuál
es la tabla “conductora”, y ejecuta un bucle accediendo a los registros de esta
tabla que cumplan las condiciones de la consulta. Para cada registro de la tabla
conductora, se ejecuta un bucle accediendo a la tabla interior, mediante los
valores actuales de la tabla conductora. Por tanto, es importante que el camino
de acceso a la tabla interior sea muy eficiente.

• Bucles Anidados Externos (Nested Loop Outer Joins) : en caso de


combinaciones externas (outer joins), si se cumplen las condiciones de elección
de Bucles Anidados, se puede utilizar el método de Bucles Anidados Externos,
en el que la tabla conductora es siempre la tabla “exterior” (mientras que, en el
método anterior, se puede elegir a una u otra tabla como tabla conductora).

• Combinaciones Hash (Hash Joins) : este método es usado para enlazar


grandes conjuntos de datos, en los que la condición de join es de igualdad. El
optimizador usa la más pequeña de las dos tablas fuentes para construir una
tabla hash sobre la clave de join, en memoria. Cuando se recuperan los
registros de la tabla más grande, se examina la tabla hash para encontrar las
filas enlazadas en la otra tabla. Esta situación es óptima cuando la tabla menor
es lo suficientemente pequeña para caber en la memoria disponible, ya que el
coste se limita a una simple lectura del dato de la tabla menor. Sin embargo, si
la tabla hash es demasiado grande, el optimizador la divide en varias
particiones, que se escriben a diferentes segmentos temporales de disco, que
son leidos a medida que son necesitados, lo que disminuye la eficiencia.

• Combinaciones Hash en Joins Externos (Hash Join Outer Joins) : este


método es muy similar al anterior, pero en el caso de combinaciones externas.
La tabla conductora es siempre la tabla externa, y se construye la tabla hash
sobre ella. Se recorre la tabla interior, comprobando en la tabla hash la
existencia de datos en la tabla exterior. Se preservan los registros de la tabla
exterior que no tengan equivalente en la interior.

• Combinaciones de Ordenación y Fusión (Sort Merge Joins) : consisten en


una fusión de los dos conjuntos de datos, previamente ordenados por las
columnas de la condición de join. No existe el concepto de tabla conductora o
directora. Se utilizan para combinar registros de dos fuentes independientes,
especialmente si ya están ordenados mediante las columnas de la condición de
join, o si la condición de join incluye algún operador que no sea de igualdad. En

Optimizacion de Oracle SQL Javier Navarro Grau Página 6 de 29


otro caso, es mejor utilizar las combinaciones hash. Existe un método similar,
para los outer joins, denominado Sort Merge Outer Joins.

• Combinaciones Cartesianas (Cartesian Joins) : consisten en la combinación


de dos fuentes de registros, entre las que no hay definida ninguna condición de
join. Su coste es muy elevado, en función de los volúmenes de las dos fuentes
de registros.

• Combinaciones Externas Completas (Full Outer Joins) : consisten en


combinaciones externas en las que se deben preservar los registros de ambas
fuentes de datos (usando las palabras clave FULL OUTER JOIN).

• Anti-Combinaciones (Anti-Joins) : son combinaciones en las que se


devuelven los registros de la primera fuente de datos que no cumplen las
condiciones impuestas a la segunda fuente (operadores NOT IN con
subconsultas ó NOT EXISTS).

• Semi-Combinaciones (Semi-Joins) : son combinaciones en las que se


devuelven los registros de la primera fuente de datos que cumplen las
condiciones impuestas a la segunda fuente (operadores IN con subconsultas ó
EXISTS).

Optimización de Sentencias en 'Estrella'

Algunos data warehouse son diseñados como esquemas en estrella, lo que incluye
una gran tabla de hechos y varias pequeñas tablas de dimensiones. En la primera se
almacena información básica y en las demás se guarda información de atributos de la tabla
de hechos.

Una consulta en estrella es una unión entre una tabla de hechos y un cierto número
de tablas de dimensiones, unidas por relaciones clave primaria – clave ajena, y sin relación
entre las tablas de dimensiones. El Optimizador Basado en Costes es capaz de identificar
este tipo de relación y de crear un plan de ejecución eficiente. El Optimizador Basado en
Reglas no presenta actividad optimizadora específica en estos casos.

Una típica tabla de hechos contiene claves y medidas. Por ejemplo la medida
Importe de ventas y las claves Fecha, Producto y Mercado (que conectan con las
correspondientes tablas de dimensiones). La tabla de hechos tiene, normalmente, un
indice concatenado en las columnas de la clave para facilitar este tipo de unión o bien
indices independientes para cada columna de la clave.

Cómo especificar el tipo de optimización

Mediante la modificación del parámetro de INIT.ORA denominado


OPTIMIZER_MODE, se consigue la determinación del tipo de optimización. Si se da el
valor RULE, el optimizador funciona mediante Reglas (RCO). Si se da el valor CHOOSE, el
optimizador elegirá Costes (CBO), siempre que existan estadísticas sobre las tablas, o se
presenten sugerencias (hints) por parte del programadador. Si se ha fijado CHOOSE, pero
no existen estadísticas o sugerencias, el Optimizador trabajará por Reglas (RCO). En

Optimizacion de Oracle SQL Javier Navarro Grau Página 7 de 29


función de otros valores del parámetro, se utilizará el CBO enfocado a un determinado
objetivo.

Optimización basada en costes


Por defecto, el punto fuerte del Optimizador Basado en Costes es la cantidad de
datos tratados por segundo, al tiempo que dedica el mínimo de recursos a la solución de la
query. Es decir, se trabaja en dos direcciones: mínimos recursos aplicables, para obtener
en el mínimo tiempo el primer registro accedido por la consulta empleada (mínimo tiempo
de respuesta).

No obstante es posible potenciar, según la tarea a realizar, una u otra prestación.

 Para aplicaciones de tipo batch, como Oracle Reports, es preferible optimizar para
la máxima productividad : se disminuye el tiempo total de tarea, no importando
tanto el tiempo de respuesta.

 Para aplicaciones interactivas, como Oracle Forms o consultas en SQL*Plus,


optimizar para el mejor tiempo de respuesta.

El CBO determina cuál de los planes de ejecución es mas eficiente, teniendo en


cuenta los caminos de acceso disponibles y factorizando la información basada en
estadísticas de los objetos del esquema (tablas o índices) accedidos por la instrucción
SQL, además de las sugerencias de optimización colocadas como comentarios en la
instrucción SQL, y el objetivo establecido en OPTIMIZER_MODE.

Cuando en Oracle se diseñan nuevas prestaciones para la base de datos se utiliza


exclusivamente la CBO como medio de optimización. En general consta de tres etapas :

1. Realización de planes potenciales de recuperación de registros.


2. Estimación del coste por plan teniendo en cuenta las estadísticas almacenadas
en el diccionario de datos disponibles para cada objeto incluido en la query. El
calculo de coste se basa en los recursos estimados para el ordenador
incluyendo Entrada/Salida, CPU y memoria.
3. Selección del plan de menor coste.

Objetivo de la estimación basada en costes

El parámetro de INIT.ORA permite seleccionar y adaptar el comportamiento del


optimizador a nuestras necesidades :

• CHOOSE: Este es el valor por defecto para el parámetro. Se decide el uso de


CBO, si hay estadísticas disponibles, en cuyo caso el objetivo a alcanzar es la
mayor productividad (registros por unidad de tiempo). Si las estadísticas son
incompletas (sólo algunos de los objetos han sido analizados) se obtiene un
plan de ejecución suboptimizado : se puede tomar como alternativa información
interna como número de bloques de datos fijados por la tabla. Si no hay
estadísticas, el optimizador decide usar el enfoque de Reglas (RBO).

Optimizacion de Oracle SQL Javier Navarro Grau Página 8 de 29


• ALL_ROWS. El optimizador emplea una aproximación CBO para todos los
registros de la consulta. El objetivo es el de alcanzar la mayor productividad
(mínimos recursos utilizados para terminar todas las partes de la instrucción).

• FIRST_ROWS_n : La optimización es CBO, pero se da prioridad al mejor


tiempo de respuesta para obtener los primeros n registros. N puede ser 1, 10,
100, o 1000.

• FIRST_ROWS : El optimizador utiliza una mezcla de CBO y reglas heurísticas,


para hallar el mejor plan que ofrezca con la mayor rapidez los registros iniciales.
A veces la parte heurística implica un coste mas alto. Este valor
(FIRST_ROWS) se dispone para compatibilidad con versiones anteriores y el
plan de estabilidad.

• RULE : La optimización se basa en reglas, con independencia de la presencia


de estadísticas.

El parámetro OPTIMIZER_GOAL puede sobrescribir la forma y objetivos de


optimización, fijadas globalmente por OPTIMIZER_MODE, para una sesión individual,
mediante la sentencia ALTER SESSION. El valor de este parámetro afecta la optimización
de las instrucciones SQL utilizadas por el usuario incluyendo las que corresponden a
procedimientos almacenados y funciones, durante la duración de la sesión. Los valores
que puede tomar son los mismos que los de OPTIMIZER_MODE.

Estadísticas para la estimación basada en Costes


Las estadísticas sobre los objetos de la base de datos Oracle se almacenan en el
diccionario de datos, y deben ser mantenidas regularmente para que sean representativas
de los datos. Pueden ser recogidas mediante el paquete DBMS_STATS o el comando
ANALYZE.

• Para versiones 8i o posteriores, usar el paquete DBMS_STATS.


• Para versiones anteriores a 8i, usar la instrucción ANALYZE.

Mediante el uso de unas estadísticas actualizadas, el CBO puede crear el mejor


plan de ejecución, con el menor coste. El CBO usa las estadísticas para calcular la
selectividad de predicados (la fracción de registros de una tabla que escoge el
predicado), y estimar el coste de un determinado camino de acceso y el orden optimo de
combinación con otras tablas.

Lo lógico es realizar capturas de estadística de forma periódica y automática. Se


debe hacer puntualmente, cada vez que se cambia la estructura de un objeto, o si se han
actualizado muchos registros en una tabla en poco tiempo. Las estadísticas generadas, por
tipo de objeto o acción, incluyen :

• Para tablas : el número de registros, número de bloques y la longitud media de


registro.
• Para columnas : el número de valores distintos (NDV) en la columna, el número
de nulos en la columna, y la distribución de datos (histograma).

Optimizacion de Oracle SQL Javier Navarro Grau Página 9 de 29


• Para índices : el número de bloques hoja (leaf blocks), los niveles, y el factor de
agrupamiento (clustering).
• Para el sistema : el rendimiento y uso de entrada/salida, y el rendimiento y uso
de CPU.

Oracle utiliza diversas técnicas con el fin de obtener las estadísticas para el CBO :

• Estimación basada en muestreo aleatorio de datos.


• Cálculo exacto.
• Métodos de recogida de estadísticas definidas por el usuario.

En caso de no existencia de estadísticas para un determinado objeto utilizado en


una sentencia, el optimizador utiliza los siguientes valores por defecto :

• Para tablas : 100 registros, 100 bloques y 20 bytes de longitud media por
registro.
• Para tablas remotas : 2000 registros y 100 bytes de longitud media por registro.
• Para índices : 25 bloques hoja, un nivel y 100 claves distintas.

Características disponibles con la Optimización Basada en Costes

Las siguientes características están disponibles sólo si se utiliza el Optimizador


Basado en Costes (CBO) :

• Tablas e índices particionados, y tablas organizadas por índices

• Índices de clave inversa, e índices basados en funciones

• Cláusulas SAMPLE en sentencias SELECT

• Consultas paralelas y DML paralelo

• Transformaciones en estrella, y consultas en estrella

• Optimizador extensible

• Re-escritura de consultas con vistas materializadas

• Combinaciones hash

• Índices bitmap

• Index Skip Scans

Recogida de estadísticas

Optimizacion de Oracle SQL Javier Navarro Grau Página 10 de 29


Comando ANALYZE

El comando ANALYZE actualmente genera estadísticas para Optimizacion Basada


en Costes. No obstante el uso de ANALYZE para este propósito es poco recomendable por
diversos motivos :

• ANALYZE siempre se ejecuta serialmente, no de forma paralela.


• ANALYZE calcula estadísticas globales para tablas particionadas e indices, en
lugar de recogerlas localmente en cada partición. Esto es causa de problemas
en algunas estadisticas, como el numero de valores diferentes en una columna.
• ANALYZE no puede sobreescribir o borrar algunos de los valores de
estadísticas que hayan sido recogidas por DBMS_STATS.
• En el futuro ANALYZE no recogerá estadísticas necesitadas por el CBO.

ANALYZE, en cambio, puede recoger otro tipo de información (que no es utilizada


por el optimizador), como registros encadenados y la integridad estructural de indices,
tablas y clusters (DBMS_STATS no puede recoger esta información).
Para recoger estadísticas de una tabla o índice, el comando ANALYZE podría ser :

ANALYZE TABLE nombre-tabla COMPUTE STATISTICS;

ANALYZE INDEX nombre-indice COMPUTE STATISTICS;

ANALYZE TABLE nombre-tabla ESTIMATE STATISTICS SAMPLE 1000 ROWS;

ANALYZE TABLE nombre-tabla ESTIMATE STATISTICS SAMPLE 20 PERCENT;

ANALYZE TABLE nombre-tabla DELETE STATISTICS;

El método COMPUTE genera estadísticas exactas, ya que procesa todos los


registros de la tabla o índice. El método ESTIMATE es más rápido, ya que se basa en una
muestra aleatoria de los registros. Por el contrario, sus estadísticas son menos fiables. El
método DELETE sirve para borrar estadísticas que se consideren poco fiables, sin generar
nuevas estadísticas.

Paquete DBMS_STATS

Puede usarse para el mantenimiento completo de estadísticas, desde la generación


hasta el borrado incluyendo la identificación (nombrado) de las estadísticas recogidas. Se
aplica para tablas, índices, columnas y particiones. No sirve globalmente para clusters (hay
que analizar cada componente de forma aislada), ni para particiones (análisis separados
por partición). Permite recoger :

• Estadísticas sobre el sistema, recogidas mediante


GATHER_SYSTEM_STATS y recuperadas mediante GET_SYSTEM_STATS.
SET_SYSTEM_STATS permite dar valores arbitrarios a estadísticas del
sistema.
• Estadísticas sobre tablas, mediante GATHER_TABLE_STATS, recuperadas
mediante GET_TABLE_STATS.

Optimizacion de Oracle SQL Javier Navarro Grau Página 11 de 29


• Estadísticas sobre índices, mediante el uso de GATHER_INDEX_STATS y de
GET_INDEX_STATS.
• Estadísticas sobre todos los objetos de un esquema, mediante el uso de
GATHER_SCHEMA_STATS.
• Estadísticas sobre todos los objetos de una base de datos, mediante el uso
de GATHER_DATABASE_STATS.

Las estadísticas generadas se almacenan en el diccionario de datos, a menos que


se especifique una tabla de almacenamiento de estadísticas, como parámetro del
procedimiento correspondiente. Las vistas del diccionario de datos que contienen las
estadísticas generadas son :

• DBA_TABLES
• DBA_TAB_COL_STATISTICS
• DBA_INDEXES
• DBA_CLUSTERS
• DBA_TAB_PARTITIONS
• DBA_TAB_SUBPARTITIONS
• DBA_IND_PARTITIONS
• DBA_IND_SUBPARTITIONS
• DBA_PART_COL_STATISTICS
• DBA_SUBPART_COL_STATISTICS

Histogramas

El Optimizador Basado en Costes puede usar histogramas de valores de datos para


obtener una estimación fiable de la distribución de los datos de una columna. Un
Histograma particiona los valores de una columna en bandas, de modo que todos los
valores de la columna en una banda caen dentro del mismo rango. Asi los Histogramas
suministran una superior estimación selectiva para datos sesgados, resultando en óptimos
planes de ejecucion con distribuciones no uniformes de datos.

Una de las tareas del CBO es determinar la selectividad de los predicados que
aparecen en las querys. Las estimaciones de selectividad se utilizan para decidir si usar o
no un índice, y el orden en el que combinar tablas. El problema surge cuando los valores
de una columna no están uniformemente distribuidos. En estos casos, es útil guardar
histogramas de la distribución de sus valores.

Se debe tener cuidado en la elección de aquellas columnas para las que se


generen histogramas, ya que pueden afectar al rendimiento. Se deben guardar únicamente
cuando mejoren de forma significativa la eficiencia de las consultas. El espacio utilizado
para almacenar un histograma depende del tamaño de la muestra elegida. En general, se
debe crear histogramas sólo para aquellas columnas que se utilicen frecuentemente en la
cláusula WHERE de las consultas, y que se sepa que tienen una distribución poco
uniforme de valores. Si la distribución de valores de una columna es uniforme, no es
necesario utilizar histogramas. Si la distribución de valores de la columna varía
constantemente, será necesario recalcular su histograma constantemente, para reflejar la
situación de forma exacta, con el consiguiente uso de recursos.

Para crear histogramas sobre una columna de una tabla, se utiliza el parámetro
METHOD_OPT del procedimiento GATHER_TABLE_STATS del paquete DBMS_STATS :

Optimizacion de Oracle SQL Javier Navarro Grau Página 12 de 29


BEGIN
DBMS_STATS.GATHER_TABLE_STATS( ’SCOTT’, ’EMP’,
METHOD_OPT => ’FOR COLUMNS SIZE 10 SAL’ );
END;

Esta llamada genera un histograma de diez particiones para la columna SAL de la


tabla EMP del usuario SCOTT. En general, es mejor que la base de datos determine el
número de particiones del histograma, mediante el valor AUTO.

Los histogramas pueden ser :

• Basados en alturas : cada partición contiene aproximadamente el mismo


número de valores, por lo que se guarda el máximo valor de la columna para
cada partición.

• Basados en valores : existen menos valores distintos de la columna en la tabla


que particiones en el histograma correspondiente, por lo que cada partición
refleja un valor y el número de ocurrencias de éste.

Para visualizar los histogramas, se cuenta con las siguientes vistas del diccionario :

• DBA_HISTOGRAMS
• DBA_PART_HISTOGRAMS
• DBA_SUBPART_HISTOGRAMS
• DBA_TAB_COL_STATISTICS

Caminos de acceso a los datos


Los caminos de acceso son las maneras en las que los datos son recuperados de la
base de datos. Las formas más comunes de acceder a un determinado registro de una
tabla referenciada por una sentencia SQL son :

- Mediante un acceso completo a la tabla (full table scan), en el que se accede a todos
sus registros. Se realiza una lectura secuencial de los bloques que componen la tabla,
(mejorándose el rendimiento con la lectura simultánea de varios bloques, indicada por
el parámetro de INIT.ORA DB_FILE_MULTIBLOCK_READ_COUNT), descartandose
aquellos que no cumplan los criterios de selección de la clausula WHERE. Este acceso
es utilizado en aquellos casos en que :

- El optimizador es incapaz de utilizar un camino de acceso mediante índice, ó

- El optimizador supone que el subconjunto resultante de la consulta es un


porcentaje importante del total de registros de la tabla, ó

- La tabla es muy pequeña y se puede cargar en memoria en una única


operación de entrada/salida, ó

- En general, cuando el optimizador perciba que el número de operaciones de


E/S va a ser menor que con los caminos de acceso que utilicen índices.

Optimizacion de Oracle SQL Javier Navarro Grau Página 13 de 29


- Mediante acceso por identificador de registro (ROWID scan) : en el que se utiliza el
identificador de registro, un valor único que especifica la posición física exacta del
registro en la base de datos. Este valor puede ser recuperado por una sentencia
SELECT y utilizado posteriormente en otras sentencias que recuperen el registro en
cuestión (con limitaciones, ya que el ROWID de un registro puede variar a
consecuencia de actualizaciones en el valor de sus campos). Con mayor frecuencia, el
acceso por ROWID es utilizado como segundo paso del acceso por índice (los índices
contienen el identificador de los registros a los que apuntan).

- Mediante un acceso por índice (index scan), en el que se usan valores indicados en
la sentencia SQL, para las columnas de la tabla que forman parte del índice. Si una
sentencia utiliza únicamente columnas que forman parte de uno de sus índices, se
utilizan estos valores, no necesitándose el acceso a la tabla mediante ROWID. En caso
contrario, se realiza el acceso mediante ROWID para recuperar los valores del resto de
las columnas. Un acceso mediante índice puede ser :

- Acceso por índice único (index unique scan) : en el que se utilizan valores de
todas las columnas de un índice UNIQUE de la tabla, con condiciones de
igualdad, por lo que se recupera un único registro ( o ninguno ).

- Acceso por rango de índice (index range scan) : en el que se utilizan valores de
algunas o todas las columnas de un índice (UNIQUE ó no) de la tabla, con
condiciones de igualdad o no, por lo que se recupera un número indeterminado
de registros. Normalmente este acceso se realiza en orden ascendente de los
valores de las columnas del índice, a no ser que se solicite mediante la clausula
ORDER BY que se recuperen de forma descendente.

- Acceso rápido al índice completo (fast full index scan) : se da cuando se van a
utilizar únicamente columnas del índice, aunque no se utilicen las primeras. Se
realiza un full scan sobre los bloques del índice, en vez de sobre los bloques
que componen la tabla. En el índice, debe haber alguna columna NOT NULL
(para asegurar que hay un registro en el índice por cada registro de la tabla), y
es conveniente analizar de vez en cuando el índice, para que el optimizador por
costes tenga en cuenta esta posibilidad.

- Acceso mediante combinaciones de índices (index joins) : se da cuando todas


las columnas necesarias para la consulta están presentes, en el conjunto de
varios índices, y la optimización por costes está disponible.

Plan de ejecución
El plan de ejecución es la secuencia de operaciones de base de datos que es
creada por el optimizador a partir de una sentencia SQL, para poder ejecutarla. Es
posible obtener el plan de ejecución de cualquier sentencia SQL, sin tener que
ejecutarla, mediante la sentencia EXPLAIN PLAN. Esta sentencia produce su
resultado en forma de registros insertados en una tabla denominada PLAN_TABLE.

El plan de ejecución para una misma sentencia SQL varía a lo largo del tiempo, en
función del modo de optimización seleccionado, los índices que se añadan o
eliminen, los análisis que se realicen para el optimizador por costes, la cantidad de
datos de las tablas, etc, lo cual dificulta el análisis a priori de las sentencias SQL. La

Optimizacion de Oracle SQL Javier Navarro Grau Página 14 de 29


sentencia EXPLAIN PLAN puede ayudar, por lo menos, a verificar que una
determinada sentencia realiza una secuencia de operaciones “recomendables”.
Existen otras herramientas de Oracle, que sirven para el análisis de las sentencias
SQL, una vez ha finalizado su ejecución sobre un determinado estado de la base de
datos.

Definición de la tabla PLAN_TABLE

La tabla PLAN_TABLE no suele estar creada por defecto en la base de datos


Oracle. Para crearla, se utiliza un fichero llamado UTLXPLAN.SQL, cuya ubicación varía,
en función del sistema operativo en el que esté instalado Oracle. Este fichero se debe
ejecutar en cada esquema de base de datos que necesite utilizar la instrucción EXPLAIN
PLAN.

Los registros insertados en la tabla PLAN_TABLE, mediante la sentencia EXPLAIN


PLAN, para una determinada sentencia SQL, forman un árbol de operaciones de base de
datos. Cada operación, dentro de este árbol, recoge el resultado creado por sus
operaciones “hijas”, efectúa su tarea y envía el resultado a su operación “madre”. La
operación “raíz” dentro del árbol es la que devuelve el resultado final de la ejecución de la
sentencia SQL.

Campos habituales dentro de la tabla PLAN_TABLE son (con posibles variaciones


en el nombre) :

• STATEMENT_ID : identificador de la sentencia, sirve para distinguir las


diferentes sentencias analizadas, dentro de la tabla.
• TIMESTAMP : indica la fecha y hora de realización del plan de ejecución.
• ID : identificador de la operación, dentro de la sentencia.
• PARENT_ID : identificador de la operación “madre” de ésta.
• POSITION : orden de la operación entre sus “hermanas”.
• OPERATION : operación de base de datos realizada.
• OPTIONS : opciones que se aplican a la operación.
• OBJECT_OWNER : propietario del objeto sobre el que se hace la operación.
• OBJECT_NAME : nombre del objeto sobre el que se hace la operación.
• SEARCH_COLUMNS : nombre de las columnas de búsqueda, si las hay.

Operaciones y Opciones de la tabla PLAN_TABLE

Cada registro de PLAN_TABLE se corresponde con una determinada operación de


base de datos. Cada operación posible, dentro de un plan de ejecución, puede ser
modificada mediante una serie de opciones. Las principales operaciones, con sus
respectivas opciones, son :

• TABLE ACCESS : operación de acceso a datos de una tabla. Sus principales opciones
son :

• FULL : se accede a todos los registros de la tabla.


• SAMPLE : se realiza un muestreo de registros de la tabla.

Optimizacion de Oracle SQL Javier Navarro Grau Página 15 de 29


• BY ROWID RANGE : se recuperan los registros de un rango de
ROWIDs.
• SAMPLE BY ROWID RANGE : se recupera una muestra de los registros
de un rango de ROWIDs.
• BY USER ROWID : se recuperan registros mediante ROWIDs
proporcionados explícitamente en la sentencia SQL.
• BY INDEX ROWID : se recuperan registros mediante ROWIDs
proporcionados por una operación de acceso con índice.
• BY GLOBAL INDEX ROWID : en el caso de tablas particionadas, se
recuperan registros mediante ROWIDs de índices globales de la tabla.
• BY LOCAL INDEX ROWID : para tablas particionadas, se recuperan
registros mediante ROWID de índices locales de particiones.

• INDEX : operación de acceso a datos mediante índice. Sus principales opciones :

• UNIQUE SCAN : recuperación de un único identificador de registro.


• RANGE SCAN : recuperación de una serie de identificadores de registro,
en orden ascendente del índice.
• RANGE SCAN DESCENDING : recuperación de una serie de ROWIDs,
en orden descendente del índice.

• VIEW : recuperación de datos de una vista.

• SEQUENCE : recuperación de datos de una secuencia.

• REMOTE : recuperación de datos de una base de datos remota.

• PARTITION : recuperación de datos de particiones de una tabla. Algunas de sus


opciones son :

• SINGLE : acceso a una única partición


• ITERATOR : acceso a varias particiones
• ALL : acceso a todas las particiones de la tabla

• SORT : operaciones de ordenación y agrupamiento de datos. Algunas opciones :

• AGGREGATE : resultado de agrupaciones sin clausula GROUP BY.


• UNIQUE : ordenación para eliminar duplicados.
• GROUP BY : resultado de agrupaciones con clausula GROUP BY.
• JOIN : ordenación previa a una combinación MERGE JOIN.
• ORDER BY : ordenación de acuerdo a una clausual ORDER BY.

• COUNT : devuelve el número de registros de una tabla.

• FILTER : toma un conjunto de registros y devuelve el subconjunto que cumpla con una
serie de restricciones.

• FIRST ROW : devuelve únicamente el primer registro de una consulta

Optimizacion de Oracle SQL Javier Navarro Grau Página 16 de 29


• FOR UPDATE : recupera y bloquea un conjunto de registros, por si es necesario
hacerles alguna modificación.

• AND-EQUAL : combina varios conjuntos de ROWIDs, y devuelve la intersección entre


ellos, eliminando duplicados.

• HASH JOIN : operación de combinación de dos conjuntos de registros.

• MERGE JOIN : operación de combinación de dos conjuntos de registros, previamente


ordenados. Puede tener la opción OUTER, entre otras.

• NESTED LOOPS : operación de combinación de dos conjuntos de registros. Puede


tener la opción OUTER, entre otras.

• UNION : esta operación toma dos conjuntos de registros y devuelve su unión,


eliminando registros duplicados.

• CONCATENATION : esta operación toma dos conjuntos de registros y devuelve su


unión, sin eliminar duplicaciones.

• INTERSECTION : toma dos conjuntos de registros y devuelve su intersección.

• MINUS : toma dos conjuntos de registros y devuelve los registros del primero que no
estén en el segundo, eliminando duplicaciones.

• CONNECT BY : recupera un conjunto de registros en orden jerárquico.

Comando EXPLAIN PLAN

El comando EXPLAIN PLAN es el creador de los datos de la tabla PLAN_TABLE.


La forma más sencilla de usarlo es :

EXPLAIN PLAN FOR sentencia;

Esta instrucción calcula el plan de ejecución para la sentencia, y lo almacena en la


tabla PLAN_TABLE. Dado que no se conoce el identificador de sentencia que se haya
podido generar, se puede buscar en PLAN_TABLE mediante la columna TIMESTAMP,
aproximadamente, por la fecha y hora. Para dar un identificador de sentencia conocido :

EXPLAIN PLAN SET STATEMENT_ID = ‘identificador’


FOR sentencia;

De esta manera, se pueden recuperar los registros de PLAN_TABLE mediante la


columna de identificación de sentencia. Dado que los registros de PLAN_TABLE, para una
determinada sentencia, forman un árbol, la mejor manera de visualizarlos es mediante un
SELECT con la opción CONNECT BY :

SELECT LPAD( ‘ ‘, LEVEL – 1 ) || ‘ ‘ || OPERATION || ‘ ‘ ||


OPTIONS || ‘ ‘ || OBJECT_NAME PLAN
FROM PLAN_TABLE
CONNECT BY PRIOR ID = PARENT_ID
AND PRIOR STATEMENT_ID = STATEMENT_ID

Optimizacion de Oracle SQL Javier Navarro Grau Página 17 de 29


START WITH ID = 0
AND STATEMENT_ID = ‘identificador’;

Esta sentencia visualiza las operaciones de base de datos de una sentencia, en


forma jerárquica, empezando por la raíz e indentando las sucesivas operaciones “hijas”.

Optimización basada en Reglas

Introducción a la Optimización de Reglas

El optimizador basado en reglas ha sido el principal método de optimización de


Oracle hasta que el optimizador basado en costes, introducido en la versión 7, ha ido
ganando en prestaciones. Actualmente se desaconseja la utilización del optimizador
basado en reglas, excepto para aplicaciones desarrolladas originalmente sobre Oracle 6 ó
versiones anteriores, o explícitamente para este optimizador sobre versiones 7 y
posteriores.

El parámetro de INIT.ORA denominado OPTIMIZER_MODE determina la elección


del optimizador. Si tiene el valor RULE, se utiliza siempre el optimizador basado en reglas.
Si tiene el valor CHOOSE, se utiliza el optimizador basado en costes, a no ser que no haya
estadísticas sobre las tablas, y no se haya indicado “hints” en las sentencias (entonces se
utiliza el basado en reglas).

El método empleado por el optimizador basado en reglas es el siguiente : se analiza


la sentencia SQL en cuestión, obteniéndose varios planes de ejecución posibles. Se
clasifican estos planes en función del ranking de sus operaciones, y se elige el plan con
menor ranking. El ranking de operaciones ha sido creado por Oracle, a partir de datos de
tiempos medios de CPU, número de operaciones de Entrada/Salida, etc, de cada tipo de
operación.

Caminos de acceso a los datos

El ranking elaborado por Oracle para los caminos de acceso a los datos es, de
menor a mayor (mejor cuanto más pequeño el ranking) :

1. Registro único, por ROWID : es el que se consigue buscando explícitamente


por ROWID, o con la clausula WHERE CURRENT OF.
2. Registro único, por combinación de cluster : se consigue combinando tablas
de un mismo cluster, para obtener un único registro, utilizando únicamente
columnas de la clave de cluster.
3. Registro único, por clave de cluster hash con clave única o primaria : se
consigue utilizando las columnas de un cluster hash, para obtener un único
registro.
4. Registro único, por clave única o primaria : se consigue utilizando en la
cláusula WHERE todas las columnas de un índice único o clave primaria, en
condiciones de igualdad, uniéndolas con operadores AND, por lo que se
recupera un único registro.
5. Combinación de cluster : se consigue combinando tablas almacenadas en el
mismo cluster, mediante igualdad de las columnas de la clave del cluster.

Optimizacion de Oracle SQL Javier Navarro Grau Página 18 de 29


6. Clave de cluster hash : se consigue utilizando las columnas de la clave de un
cluster hash creado sobre la tabla.
7. Clave de cluster indexada : se consigue utilizando todas las columnas de una
clave de custer indexada.
8. Índice compuesto : se consigue utilizando todas las columnas de un índice
compuesto por más de una columna, en condiciones de igualdad.
9. Índice de columna única : se consigue utilizando, en condiciones de igualdad,
las columnas de uno o varios índices de columna única.
10. Rango restringido de columnas indexadas : se consigue cuando se
especifican una o varias columnas de un índice, de manera que se restringe un
rango de los datos (p.ej. con el operador BETWEEN).
11. Rango no restringido de columnas indexadas : se consigue cuando se
especifican una o varias columnas de un índice, pero no se restringe a un rango
cerrado de los datos.
12. Combinación de conjuntos ordenados : se consigue cuando se hace join
entre dos tablas que no forman parte de un cluster, mediante columnas en
condiciones de igualdad. Se ordenan ambas tablas por las columnas del join, y
después se fusionan (merge) para obtener la combinación de ambas.
13. MAX ó MIN de columnas indexadas : se consigue buscando el MAX ó MIN de
la primera columna de un índice, si no hay otras condiciones que limiten el
conjunto de datos.
14. ORDER BY de columnas indexadas : se consigue utilizando en una cláusula
ORDER BY las primeras columnas de un índice.
15. Acceso completo a tabla : es el último camino de acceso dentro del ranking.

Ajuste de Sentencias SQL. Traza SQL y utilidad TKPROF


La sentencia EXPLAIN PLAN permite el estudio a priori de las sentencias SQL,
mostrando las operaciones de base de datos en que se descomponen. Esto puede dar
indicios sobre posibles ineficiencias, pero no ayuda en situaciones en las que un módulo o
informe da una respuesta lenta, y no se sabe cuál de las sentencias SQL que ejecuta es la
responsable. Para estas situaciones, Oracle proporciona la traza de SQL, un mecanismo
de recogida de información sobre la ejecución de las sentencias en la base de datos, y la
utilidad TKPROF, un programa que interpreta el resultado en bruto de la traza y produce
planes de ejecución y estadísticas.

La traza de SQL se puede activar para una determinada sesión Oracle, o para la
instancia Oracle al completo. La sobrecarga en el servidor de base de datos es mínima
para una única sesión con la traza activada, pero activar la traza para toda la instancia
puede requerir hasta un 25% del tiempo de CPU, y gran cantidad de espacio en disco para
recoger la salida en bruto de la traza.

Activar los Parámetros de Inicialización

El primer paso para utilizar la traza es dar valor a los parámetros correspondientes
de INIT.ORA. Los parámetros principales son :

• TIMED_STATISTICS : puede tener los valores TRUE ó FALSE. Si es TRUE, la traza de


SQL recogerá información de tiempos de ejecución de las sentencias, además de otras
informaciones que recoge siempre. Como inconveniente, la traza tendrá un peso aún
mayor en tiempo de CPU y entrada/salida.

Optimizacion de Oracle SQL Javier Navarro Grau Página 19 de 29


• MAX_DUMP_FILE_SIZE : establece el mayor tamaño posible (en bloques de sistema
operativo) de los ficheros generados por la traza de SQL. Si se va a analizar sesiones
de larga duración, con gran cantidad de sentencias SQL, será necesario incrementar
este parámetro, para evitar que se corten los ficheros producidos.
• USER_DUMP_DEST : indica el directorio en que se crearán los ficheros de traza
correspondientes a las sesiones analizadas. Se puede alterar a nivel de sesión
mediante ALTER SYSTEM.

Activar la traza

Para activar la traza, es necesario dar el valor TRUE al parámetro SQL_TRACE.


Esto se puede realizar en el fichero INIT.ORA, para activar la traza en toda la instancia, o a
nivel de sesión, con las posibilidades :

ALTER SYSTEM SET SQL_TRACE = TRUE;

BEGIN
DBMS_SESSION.SET_SQL_TRACE( TRUE );
END;
/

A partir del momento en que se activa la traza para una sesión, se va escribiendo
en un fichero correspondiente a ésta toda la información sobre las sentencias que se van
ejecutando, hasta el momento en que finaliza la sesión, o se desactiva la traza con las
sentencias :

ALTER SYSTEM SET SQL_TRACE = FALSE;

BEGIN
DBMS_SESSION.SET_SQL_TRACE( FALSE );
END;
/

Formateo de la traza con TKPROF

Una vez realizada la traza de una sesión, es necesario identificar el fichero de traza
correspondiente, en el directorio de destino de trazas. Suele bastar con mirar la fecha y
hora de los últimos ficheros creados, buscando aquélla que coincida con la fecha y hora de
finalización de la sesión en cuestión. Alternativamente, en caso de múltiples usuarios
realizando trazas simultáneamente, se puede variar el directorio USER_DUMP_DEST a
nivel de sesión.

La utilidad TKPROF toma como entrada un fichero de traza, y produce un informe


formateado, en función de las opciones adicionales que se le indiquen. La sintaxis de
TKPROF es la siguiente :

Optimizacion de Oracle SQL Javier Navarro Grau Página 20 de 29


TKPROF fichero-entrada fichero-salida opciones

Donde :

• fichero-entrada es el fichero generado por la traza de SQL


• fichero-salida es el nombre del fichero que creará TKPROF
• opciones pueden ser una o varias de las siguientes :
• SORT=parámetros, que indica por cuáles parámetros ordenar las
diferentes sentencias SQL. Los parámetros disponibles son los tiempos
de CPU, operaciones de entrada/salida, lecturas de bloques, etc, en
cada etapa de la ejecución (parse, execute & fetch).
• PRINT=n, que indica cuántas sentencias SQL mostrar en el informe. Es
útil cuando se combina con la anterior.
• INSERT=fichero, para crear un fichero SQL que serviría para guardar
en la base de datos las estadísticas generadas.
• SYS=YES ó SYS=NO, indicando si se debe interpretar o no las sentencias
de SQL recursivo producidas por la propia base de datos.
• EXPLAIN=usuario, indica que se realizará un EXPLAIN PLAN para
cada sentencia SQL, en el esquema del usuario indicado, y se mostrará
el plan de ejecución correspondiente en el fichero creado por TKPROF.

Interpretar el fichero de salida

Para cada sentencia SQL recogida en el fichero de traza, TKPROF emite un


informe con :

• Texto completo de la sentencia SQL ;


• Plan de ejecución correspondiente, con número de registros procesados por
cada operación ;
• Estadísticas de cada etapa de la ejecución de la sentencia SQL (interpretación,
ejecución y recogida de registros), así como de los tiempos de CPU
transcurridos, la entrada/salida realizada, y el número de veces que se ha
ejecutado.

Además, se muestran totales generales, de todas las variables. Para interpretar


correctamente el resultado de TKPROF, es conveniente ordenar el resultado (mediante el
parámetro SORT), según tiempos de CPU o operaciones de entrada/salida, para destacar
las operaciones más costosas. A la hora de optimizar una determinada sentencia SQL que
se haya detectado como costosa, se debe relativizar su coste teniendo en cuenta el
número de veces que se ejecuta. Una pequeña mejora en una sentencia que se ejecute un
gran número de veces, o un número variable de veces, puede ser más importante a la
larga, que una mejora importante en una sentencia más costosa que se ejecute un número
pequeño de veces.

Estadísticas Tabulares

TKPROF lista las estadísticas en forma de filas y columnas. Cada fila se


corresponde con una etapa del procesamiento de la sentencia SQL :

Optimizacion de Oracle SQL Javier Navarro Grau Página 21 de 29


• PARSE : en esta etapa, se traduce la sentencia a un plan de ejecución, y se
comprueba la existencia de los objetos implicados

• EXECUTE : en esta etapa, el gestor de base de datos ejecuta la sentencia. En


sentencias de manipulación de datos, se realiza la actualización. En sentencias
de consulta (SELECT), se identifican las sentencias consultadas.

• FETCH : en caso de sentencias de consulta, en esta etapa se devuelven los


registros al proceso que ha enviado la sentencia SQL al gestor de base de
datos.

Además, se incluye otra fila con el total combinado de las tres etapas. Las columnas de
cada fila son :

• COUNT : Número de veces que ha sido ejecutada la etapa en cuestión.

• CPU : Tiempo total de CPU para la etapa (sólo si TIMED_STATISTICS es TRUE).

• ELAPSED : Tiempo total transcurrido para la etapa (si TIMED_STATISTICS).

• DISK : Número total de bloques físicos leídos en la etapa.

• QUERY : Número total de buffers recuperados en modo consistente para la etapa. Este
modo suele ser utilizado para las consultas.

• CURRENT : Número total de buffers recuperados en modo actual para la etapa. Este
modo suele ser utilizado para las actualizaciones.

• ROWS : Número total de registros procesados en la etapa. En sentencias de


manipulación, los registros actualizados aparecen en la etapa EXECUTE. En consultas,
en la etapa FETCH.

Al interpretar la información sobre tiempos, se debe tener en cuenta que la resolución es de


una centésima de segundo, por lo que puede ser significativa, especialmente en sentencias de
ejecución muy rápida, que se ejecuten muchas veces. La información sobre buffers utilizados es
más fiable.

Almacenar estadísticas en la Base de Datos

Es posible, mediante un parámetro del comando TKPROF, generar un fichero de


sentencias SQL que, ejecutado en un esquema de la base de datos, cree una tabla,
llamada TKPROF_TABLE, y le inserte los registros correspondientes a los datos de la traza
procesada. Algunos de los campos de esta tabla son :

• SQL_STATEMENT : la sentencia SQL procesada.

• DATE_OF_INSERT : la fecha de inserción del registro en la base de datos.

• DEPTH : el nivel de recursión de la ejecución de la sentencia. El valor 0 indica


una sentencia ejecutada por el usuario. Un valor superior indica una sentencia
ejecutada por la propia base de datos para obtener el resultado de una
sentencia de nivel inferior.

Optimizacion de Oracle SQL Javier Navarro Grau Página 22 de 29


• PARSE_% : valores correspondientes a la fase de PARSE.

• EXE_% : valores correspondientes a la fase de EXECUTE.

• FETCH_% : valores correspondientes a la fase de FETCH.

La característica AUTOTRACE de SQL*PLUS


La herramienta SQL*Plus da la posibilidad de obtener fácilmente el plan de
ejecución y estadísticas sobre la ejecución de las sentencias SQL, a medida que éstas se
van introduciendo. Con el comando :

SET AUTOTRACE ON

se activa la característica de traza automática. Después de la ejecución de cada


sentencia, se muestra el plan de ejecución, y estadísticas sobre la ejecución. Con la opción
OFF, se desactiva la traza automática. Otras posibilidades son :

SET AUTOTRACE ON EXPLAIN

SET AUTOTRACE ON STATISTICS

Con la primera, se activa sólo la visualización del plan de ejecución. Con la


segunda, sólo la visualización de las estadísticas. Un ejemplo de las estadísticas
producidas es :

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
1055 consistent gets
0 physical reads
0 redo size
6971 bytes sent via SQL*Net to client
1416 bytes received via SQL*Net from client
11 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
143 rows processed

Ajuste manual de sentencias: Los HINTS

Propósito de los Hints

El diseñador o programador de una aplicación puede conocer información sobre los


datos que no esté disponible para el optimizador de Oracle (Sobre su distribución presente
o futura, sobre selectividad de índices, etc). Basado en esta información, puede elegir un
plan de ejecución más eficiente que el optimizador. Para este caso, Oracle proporciona los
hints (sugerencias), un mecanismo para que el programador pueda transmitir esta

Optimizacion de Oracle SQL Javier Navarro Grau Página 23 de 29


información al Optimizador Basado en Costes, para forzarlo a utilizar un plan de ejecución
alternativo.

Las sugerencias se pasan como comentarios en sentencias SQL, de manera que


no afectan al código que deba ser ejecutado sobre bases de datos sin estas
características. Se incluye el comentario-sugerencia inmediatamente después de la
palabra clave INSERT, UPDATE, DELETE y SELECT. Si no se introducen correctamente, o
no tienen significado, se ignoran, sin que la base de datos devuelva un error.

En un mismo comentario se pueden introducir varias sugerencias, empezando con


un signo más, y separando sucesivas sugerencias con espacios.

Comentarios para decidir el método de Optimización

Para decidir el método de optimización de una sentencia específica, se usan los


siguientes hints, equivalentes a valores del parámetro OPTIMIZER_MODE :

• /*+ ALL_ROWS */ : equivalente al valor ALL_ROWS


• /*+ FIRST_ROWS(n) */ : equivalente al valor FIRST_ROWS_n
• /*+ CHOOSE */ : equivalente al valor CHOOSE
• /*+ RULE */ : equivalente al valor RULE

Comentarios para decidir el método de Acceso

Para determinar el método de acceso a una tabla, se utilizan las siguientes


sugerencias :

• /*+ FULL(tabla) */ : FULL SCAN sobre la tabla indicada.


• /*+ ROWID(tabla) */ : acceso por ROWID sobre la tabla indicada.
• /*+ CLUSTER(tabla) */ : acceso por cluster a la tabla.
• /*+ HASH(tabla) */ : acceso por hash a la tabla.
• /*+ INDEX(tabla índice) */ : acceso por un determinado índice a la tabla.
• /*+ INDEX_ASC(tabla índice) */ : acceso ascendente por un determinado índice
a la tabla.
• /*+ INDEX_COMBINE(tabla índices) */ : acceso por varios índices a la tabla.
• /*+ INDEX_DESC(tabla índice) */ : acceso descendente por un determinado
índice a la tabla.
• /*+ INDEX_FFS(tabla índice) */ : acceso FAST FULL INDEX para la tabla.
• /*+ NO_INDEX(tabla índice) */ : desactiva el uso de los índices indicados.
• /*+ AND_EQUAL(tabla índices) */ : realiza un acceso AND-EQUAL sobre varios
índices de la tabla.

Comentarios para decidir el orden de combinación

Para variar el orden de combinación de tablas, Oracle proporciona las sugerencias :

Optimizacion de Oracle SQL Javier Navarro Grau Página 24 de 29


• /*+ ORDERED */ : indica que el orden de combinación de las tablas debe ser el
indicado en la cláusula FROM. Si no se indica, el optimizador elegirá el orden
que mejor le venga.
• /*+ STAR */ : indica una combinación en estrella, en la que la tabla más grande
es la última en la lista de tablas a combinar.

Comentarios para decidir el método de combinación

Para decidir el método de combinación de las tablas, existen las sugerencias :

• /*+ USE_NL(tabla1 tabla2) */ : indica un Nested Loop Join entre las tablas tabla1
y tabla2, con la tabla interior tabla1.
• /*+ USE_MERGE(tabla1 tabla2) */ : indica un Sort Merge Join entre las tablas
tabla1 y tabla2.
• /*+ USE_HASH(tabla1 tabla2) */ : indica un Hash Merge Join entre las tablas.

Comentarios para ejecución en paralelo

Los siguientes hints permiten la ejecución en paralelo de consultas :

• /*+ PARALLEL(tabla, número) */ : indica que hasta un determinado número de


servidores paralelos pueden trabajar en el acceso a la tabla.
• /*+ NO_PARALLEL(tabla) */ : indica una tabla sobre la que no se deben ejecutar
accesos en paralelo.

Comentarios adicionales

• /*+ CACHE(tabla) */ : indica que los bloques recuperados de la tabla en cuestión


sean almacenados en la cache con alta prioridad, para que no sean
descartados rápidamente. Útil para tablas pequeñas utilizadas frecuentemente.
• /*+ NO_CACHE(tabla) */ : indica que no se debe dar prioridad en la cache a los
bloques de la tabla indicada.
• /*+ UNNEST */ : indica que se pueden realizar transformaciones de
subconsultas en combinaciones con las tablas principales.
• /*+ NO_UNNEST */ : indica que no se pueden realizar transformaciones de
subconsultas.
• /*+ ORDERED_PREDICATES */ : indica que las condiciones de la cláusula
WHERE se deben ejecutar en el orden en que se han indicado.

Vistas Materializadas

Introducción

Las vistas materializadas son objetos de base de datos que contienen el resultado
de una consulta, que puede hacer referencia a objetos de la misma base de datos, o de
bases de datos remotas. Permiten una mayor eficiencia, al contener el resultado de

Optimizacion de Oracle SQL Javier Navarro Grau Página 25 de 29


consultas complejas, con el inconveniente de requerir espacio en la base de datos, y
tiempo de mantenimiento, para el refresco periódico de su contenido, de manera que esté
actualizado.

Creación de vistas materializadas

Para crear una vista materializada en un determinado esquema, la sentencia más


simple es :

CREATE MATERIALIZED VIEW nombre-vista AS consulta;

En esta definición se pueden incluir especificaciones de almacenamiento, igual que


en la definición de tablas e índices.

Refresco de vistas materializadas

En la definición de una vista materializada, se puede especificar la frecuencia de la


actualización de su contenido :

CREATE MATERIALIZED VIEW nombre-vista


REFRESH tipo-de-refresco
START WITH fecha-inicio NEXT fecha-siguiente
AS consulta;

El tipo de refresco puede ser FAST (rápido) ó COMPLETE (completo). Para poder
utilizar un refresco rápido, debe existir un registro de vista materializada, definido sobre
la tabla origen de la vista materializada. En consultas complejas, o si no hay definido
registro, puede ser obligatorio el refresco completo.

La fecha de inicio y fecha siguiente son expresiones válidas Oracle que se evalúan
en el momento de la creación, y en sucesivos refrescos, para calcular la próxima fecha en
la que se realizará.

La instrucción para crear un registro de vista materializada sobre una tabla es :

CREATE MATERIALIZED VIEW LOG ON nombre-tabla;

Se pueden incluir especificaciones de almacenamiento para el registro. En estos


registros se almacenan los cambios que sufre la tabla indicada, de manera que cuando
una vista materializada que hace referencia a ella realiza un refresco rápido, sólo tiene que
tener en cuenta los cambios indicados en el registro, desde su última fecha de refresco.

Reescritura de Consultas
Cuando el optimizador analiza una consulta de usuario y encuentra que es
compatible con la consulta asociada a una vista materializada, la consulta del usuario
puede ser reescrita en términos de la vista materializada, para obtener ventaja de ella. Al
hacer esto, se mejora el rendimiento, ya que parte del resultado ya ha sido calculado con
anterioridad. Dependiendo del coste de la reescritura, y de las condiciones adicionales que
haya que aplicar a la vista materializada, se puede optar por la reescritura.

Optimizacion de Oracle SQL Javier Navarro Grau Página 26 de 29


Para que la reescritura de consultas esté activada, es necesario que el parámetro
de INIT.ORA llamado QUERY_REWRITE_ENABLED tenga el valor TRUE.

Optimizacion de Oracle SQL Javier Navarro Grau Página 27 de 29


Estabilidad de Planes
La estabilidad de planes evita que los cambios en el entorno de la base de datos
afecten al rendimiento en la ejecución de aplicaciones. Los “cambios en el entorno” pueden
ser cambios en las estadísticas del optimizador, cambios en la configuración del
optimizador, o en parámetros que afecten al tamaño de estructuras de memoria de la base
de datos, como SORT_AREA_SIZE, u otros. La utilidad de la estabilidad de planes está en
aplicaciones en las que no se pueda arriesgar a un cambio en el rendimiento.

La estabilidad de planes preserva los planes de ejecución de las sentencias SQL de


las aplicaciones en esquemas (outlines) almacenados. Cuando se genera y almacena un
outline para una sentencia, y se le indica al optimizador que lo utilice, éste recupera el
outline y genera un plan de ejecución equivalente, sin tener en cuenta la información más
actual de la base de datos. De esta manera, se consigue inmunizar a las sentencias SQL
que se desee, de los cambios futuros en el estado de la base de datos.

La estabilidad de planes es contraria, en esencia, al método de optimización


basado en costes, ya que éste intenta utilizar la información más reciente sobre la base de
datos, mientras que la estabilidad obliga a utilizar planes de ejecución elegidos en un
tiempo pasado, que pueden haber perdido eficiencia. Se debe intentar encontrar un
equilibrio entre ambos extremos, en el desarrollo de las aplicaciones.

Creación de Outlines para Estabilidad de Planes

Un Outline consiste en un conjunto de hints equivalente al plan de ejecución que se


quiere almacenar, para una determinada sentencia. Al ejecutar una sentencia con un
outline creado, el optimizador recoge sus hints y los utiliza para crear el plan de ejecución,
que será equivalente al original.

Para activar la creación de outlines de las sentencias ejecutadas en una sesión, se


utiliza el parámetro CREATE_STORED_OUTLINES de ALTER SESSION.

ALTER SESSION SET CREATE_STORED_OUTLINES = TRUE;

Hasta el final de la sesión, o hasta que se desactive la creación de outlines dando el


valor FALSE al parámetro, se generará un outline para cada sentencia única ejecutada.
Una alternativa es generar un outline para una única sentencia, con el comando :

CREATE OUTLINE nombre


FOR CATEGORY categoría
ON sentencia;

Oracle permite ver los outlines almacenados por el usuario en la vista


USER_OUTLINES, y los hints de cada outline en la vista USER_OUTLINE_HINTS. Los
principales campos de USER_OUTLINES son :

• NAME : Nombre asignado al outline


• CATEGORY : Categoría del outline
• TIMESTAMP : Fecha y hora de creación del outline

Optimizacion de Oracle SQL Javier Navarro Grau Página 28 de 29


• VERSION : Versión de base de datos de creación del outline
• SQL_TEXT : Texto SQL de la sentencia original

Los principales campos de USER_OUTLINE_HINTS son :

• NAME : Nombre asignado al outline


• NODE : Nodo
• STAGE : Etapa
• JOIN_POS : Posición en el join
• HINT : hint para el optimizador

Uso de Outlines con la Optimización basada en Costes

Para utilizar los outlines almacenados, es necesario que esté seleccionada la


optimización basada en costes, y que el parámetro USE_STORED_OUTLINES tenga el
valor TRUE, en cuyo caso se utilizan los outlines de categoría DEFAULT, o el nombre de
una categoría de hints, en cuyo caso se utilizarán los outlines de dicha categoría. Para
utilizar un outline, el optimizador requiere que el texto de la sentencia SQL sea idéntico al
de la sentencia original, por lo que es conveniente utilizar un estilo consistente.

Optimizacion de Oracle SQL Javier Navarro Grau Página 29 de 29