Translate

miércoles, 26 de septiembre de 2012

Estadisticas Oracle optimizer plan


Estadisticas  en una base Oracle

       El optimizador de Oracle se basa en los costos y estadísticas de la base de datos, esto quiere decir que necesita información acerca de los datos almacenados en la base para poder realizar un plan de ejecución lo mas óptimo posible, esta recolección de información comprende varios puntos importantes, como puede  ser la distribución de los datos dentro de las tablas, cantidad de índices que hay sobre que columnas , lo selectivo que es cada índice, la distribución de los datos dentro de una columna indexada (clustering_factor) , como  así  también estadísticas del sistema, que pueden variar si se toman de día o de noche , ya que una base de datos durante el día puede trabajar como oltp  y por la noche como olap, además si basamos nuestras estadísticas en el costo de cpu  o de i/o.
A partir de la versión 10g hay un proceso  de mantenimiento que captura estadísticas de manera automática en horarios nocturnos, esto es por default y se puede modificar el horario o desabilitar.

       El optimizador de oracle es una tema muy complejo y apasionante ya que existe infinidad de políticas para su uso , y se podria variar su comportamiento algunos  parametros  de inicializacion como pueden ser optimizer_index_caching, optimizer_index_cost_adj, optimizer_max_permutations, etc.

Esta nota apunta a enseñar los comandos basicos e indispensables  para la recuperación  de estadísticas .

Estadísticas de un esquema completo:
exec dbms_stats.gather_schema_stats (ownname=>'CHARLY',
                                                           estimate_percent=> dbms_stats.auto_sample_size,
                                                           method_opt => 'FOR ALL COLUMNS SIZE 10',
                                                           cascade => true
                                                           degree=>4);

Aqui  voy  a explicar algunas opciones de los parámetros  mas importantes de este package :

estimate_percent=>dbms_stats.auto_sample_size : Oracle decide  que grado  de estadísticas toma .
estimate_percent=>100 : Oracle recorre  todos los objetos  del esquema y toma el 100%  de información , en bases  de datos  grandes  muchas veces  es inviable esta opción.
estimate_percent=>15 : Oracle estima y solo toma 15 % de la información de cada objeto del esquema mencionado , el dba puede ir analizando  si  con  este porcentaje de muestra alcanza .

method_opt :
for all columns size skewonly  opción que requiere mucho tiempo intensivo porque examina la distribución de valores para cada columna dentro de cada índice , DBMS_STATS descubre un índice cuyas columnas están desigualmente distribuidos, se creará histogramas para dicho índice para tomar una decision  al momento  de usar  un indice  o hacer full scn  de la tabla.
for all columns size repeat: Oracle  solo  exinara los histogramas de las columnas que ya tienen  histogramas y no buscara potenciales  nuevas columnas analizar.
for all columns size auto (default):  analizara histogramas de la columnas que Oracle considere 

casdade => true :  indica que no solo va a tomar estadísticas de la tabla sino  de los indices  asociados  a  esta.

degree=>4 : indica el grado  de paralelismo , para poder  tomar un grado  indicado  de paralelismo  podemos  utilizar  la siguiente regla :
degree = PARALLEL_THREADS_PER_CPU x CPU_COUNT

También se puede recopilar estadísticas de una tabla o índice:

exec dbms_stats.gather_index_stats('CHARLY', 'EMPLOYEES_PK', estimate_percent => 15);
exec dbms_stats..gather_table_stats('CHALY','EMPLOYEES', estimate_percent => 15);


Insercion  de estadisticar artificiales:

Nosotros  como  dba's podemos alterar  los planes del optimizer  , mediante  hint  o bien  siendo  un poco  mas radicales  directamente generando información  falsa , de esta manera el optimizer  podría  utilizar un indice que nosotros  deseamos que use.

Por ejemplo:

dbms_stats.set_index_stats(ownname=> 'CHARLY',indname => 'EMPLOYEES_IDX01',numdist=> 500);

Las estadísticas de sistema se toman  de la siguiente manera:

exec dbms_stats.gather_system_stats (gathering_mode=>'START');

exec dbms_stats.gather_system_stats (gathering_mode=>'STOP');






No hay comentarios:

Publicar un comentario