domingo, 16 de junio de 2013
UNDO Oracle
SQL > alter system set UNDO_RETENTION=300 scope=memory;
Como liberar espacio del UNDO en Oracle
Esta es una duda recurrente en los foros y busquedas en Google, y no es para menos ya que el tablespace de UNDO cuando se tiene la base de datos en Automatic Undo Management tiende a llenarse frecuentemente con valores altos (digamos horas) del parámetro UNDO_RETENTION.
Esto sucede porque el mecanismo de no bloqueo a lectores-escritores de Oracle, va a guardar una copia de los datos durante el tiempo especificado en UNDO_RETENTION; sabemos que esta configuración se mantiene para el proceso de más larga duración, sin embargo los procesos de menor duración también verán reservada esa información más allá del periodo en que se ejecuten y dentro del limite establecido por UNDO_RETENTION.
Esta situación supone un "desperdicio" de UNDO y eventualmente puede presentarse que el tablespace se llena y se lanzar un error ORA-01555, o tenemos que agregar mas espacio.
Para reaccionar a esta situación lo que podemos hacer es bajar el valor del parámetro UNDO_RETENTION al rango de minutos, teniendo cuidado de no impactar procesos actualmente en ejecución cuya duración sea mayor a ese valor, pues seguramente se presentaran errores ORA-01555.
Con esta sentencia se puede modificar este parametro, recordando que el valor esta definido en segundos:
SQL > alter system set UNDO_RETENTION=300 scope=memory;
SQL > alter system set UNDO_RETENTION=300 scope=memory;
En cuestión de minutos podremos ver como el espacio libre se amplia en el tablespace de UNDO, recomendamos tener visibilidad sobre el alert.log para reaccionar en caso de presentarse errores ORA-01555, la acción correctiva es aumentar el UNDO_RETENTION.
Espero sea de ayuda este tip, Saludos!
Si el articulo no satisfizo tus dudas, visita nuestros foros
Vea el articulo relacionado ¿Quien esta usando tu espacio de UNDO?
¿Necesitas saber más sobre índices? estos links son de los mejores textos en Internet
Oracle las sentencias que se ejecutan desde una sesión desconectada o conectada.
Oracle las sentencias que se ejecutan desde una sesión desconectada
Si consultas el tema Recopilación de scripts y consultas útiles de Oracle encontrarás la query que te copio para extraer información sobre las sentencias SQL y el usuario que las ha ejecutado. Ten en cuenta que la consulta te saca las sentencias que se encuentran en la Shared SQL Area, dentro de la Shared Pool, es decir, las que se están ejecutando o se han ejecutado y Oracle almacena para optimizar ejecuciones posteriores. Las que menos se utilizan irán desapareciendo de este àrea.
•• Últimas consultas SQL ejecutadas en Oracle y usuario que las ejecutó:
select distinct vs.sql_text, vs.sharable_mem,
vs.persistent_mem, vs.runtime_mem, vs.sorts,
vs.executions, vs.parse_calls, vs.module,
vs.buffer_gets, vs.disk_reads, vs.version_count,
vs.users_opening, vs.loads,
to_char(to_date(vs.first_load_time,
'YYYY-MM-DD/HH24:MI:SS'),'MM/DD HH24:MI:SS') first_load_time,
rawtohex(vs.address) address, vs.hash_value hash_value ,
rows_processed , vs.command_type, vs.parsing_user_id ,
OPTIMIZER_MODE , au.USERNAME parseuser
from v$sqlarea vs , all_users au
where (parsing_user_id != 0) AND
(au.user_id(+)=vs.parsing_user_id)
and (executions >= 1) order by buffer_gets/executions desc
A partir de aquí puedes sacar tanta la información que necesites tanto de v$sqlarea como de all_users. En la documentación online de Oracle tienes todos los campos de estadísticas disponibles para v$sqlarea. Igualmente los copio:
|
Column | Datatype | Description |
---|---|---|
SQL_TEXT | VARCHAR2(1000) | First thousand characters of the SQL text for the current cursor |
SQL_FULLTEXT | CLOB | All characters of the SQL text for the current cursor |
SQL_ID | VARCHAR2(13) | SQL identifier of the parent cursor in the library cache |
SHARABLE_MEM | NUMBER | Amount of shared memory used by a cursor. If multiple child cursors exist, then the sum of all shared memory used by all child cursors. |
PERSISTENT_MEM | NUMBER | Fixed amount of memory used for the lifetime of an open cursor. If multiple child cursors exist, the fixed sum of memory used for the lifetime of all the child cursors. |
RUNTIME_MEM | NUMBER | Fixed amount of memory required during execution of a cursor. If multiple child cursors exist, the fixed sum of all memory required during execution of all the child cursors. |
SORTS | NUMBER | Sum of the number of sorts that were done for all the child cursors |
VERSION_COUNT | NUMBER | Number of child cursors that are present in the cache under this parent |
LOADED_VERSIONS | NUMBER | Number of child cursors that are present in the cache and have their context heap (KGL heap 6) loaded |
OPEN_VERSIONS | NUMBER | The number of child cursors that are currently open under this current parent |
USERS_OPENING | NUMBER | Number of users that have any of the child cursors open |
FETCHES | NUMBER | Number of fetches associated with the SQL statement |
EXECUTIONS | NUMBER | Total number of executions, totalled over all the child cursors |
PX_SERVERS_EXECUTIONS | NUMBER | Total number of executions performed by Parallel eXecution Servers. The value is 0 when the statement has never been executed in parallel. |
END_OF_FETCH_COUNT | NUMBER | Number of times this cursor was fully executed since the cursor was brought into the library cache. The value of this statistic is not incremented when the cursor is partially executed, either because it failed during the execution or because only the first few rows produced by this cursor are fetched before the cursor is closed or re-executed. By definition, the value of theEND_OF_FETCH_COUNT column should be less or equal to the value of the EXECUTIONS column. |
USERS_EXECUTING | NUMBER | Total number of users executing the statement over all child cursors |
LOADS | NUMBER | Number of times the object was loaded or reloaded |
FIRST_LOAD_TIME | VARCHAR2(19) | Timestamp of the parent creation time |
INVALIDATIONS | NUMBER | Total number of invalidations over all the child cursors |
PARSE_CALLS | NUMBER | Sum of all parse calls to all the child cursors under this parent |
DISK_READS | NUMBER | Sum of the number of disk reads over all child cursors |
DIRECT_WRITES | NUMBER | Sum of the number of direct writes over all child cursors |
BUFFER_GETS | NUMBER | Sum of buffer gets over all child cursors |
APPLICATION_WAIT_TIME | NUMBER | Application wait time (in microseconds) |
CONCURRENCY_WAIT_TIME | NUMBER | Concurrency wait time (in microseconds) |
CLUSTER_WAIT_TIME | NUMBER | Cluster wait time (in microseconds) |
USER_IO_WAIT_TIME | NUMBER | User I/O Wait Time (in microseconds) |
PLSQL_EXEC_TIME | NUMBER | PL/SQL execution time (in microseconds) |
JAVA_EXEC_TIME | NUMBER | Java execution time (in microseconds) |
ROWS_PROCESSED | NUMBER | Total number of rows processed on behalf of this SQL statement |
COMMAND_TYPE | NUMBER | Oracle command type definition |
OPTIMIZER_MODE | VARCHAR2(10) | Mode under which the SQL statement was executed |
OPTIMIZER_COST | NUMBER | Cost of this query given by the optimizer |
OPTIMIZER_ENV | RAW(703) | Optimizer environment |
OPTIMIZER_ENV_HASH_VALUE | NUMBER | Hash value for the optimizer environment |
PARSING_USER_ID | NUMBER | User ID of the user that has parsed the very first cursor under this parent |
PARSING_SCHEMA_ID | NUMBER | Schema ID that was used to parse this child cursor |
PARSING_SCHEMA_NAME | VARCHAR2(30) | Schema name that was used to parse this child cursor |
KEPT_VERSIONS | NUMBER | Number of child cursors that have been marked to be kept using the DBMS_SHARED_POOL package |
ADDRESS | RAW(4 | 8) | Address of the handle to the parent for this cursor |
HASH_VALUE | NUMBER | Hash value of the parent statement in the library cache |
OLD_HASH_VALUE | NUMBER | Old SQL hash value |
PLAN_HASH_VALUE | NUMBER | Numerical representation of the SQL plan for this cursor. Comparing one PLAN_HASH_VALUE to another easily identifies whether or not two plans are the same (rather than comparing the two plans line by line) |
MODULE | VARCHAR2(64) | Contains the name of the module that was executing at the time that the SQL statement was first parsed as set by callingDBMS_APPLICATION_INFO .SET_MODULE |
MODULE_HASH | NUMBER | Hash value of the module that is named in the MODULE column |
ACTION | VARCHAR2(64) | Contains the name of the action that was executing at the time that the SQL statement was first parsed as set by callingDBMS_APPLICATION_INFO .SET_ACTION |
ACTION_HASH | NUMBER | Hash value of the action that is named in the ACTION column |
SERIALIZABLE_ABORTS | NUMBER | Number of times the transaction fails to serialize, producing ORA-08177 errors, totalled over all the child cursors |
OUTLINE_CATEGORY | VARCHAR2(64) | If an outline was applied during construction of the cursor, then this column displays the category of that outline. Otherwise the column is left blank. |
CPU_TIME | NUMBER | CPU time (in microseconds) used by this cursor for parsing, executing, and fetching |
ELAPSED_TIME | NUMBER | Elapsed time (in microseconds) used by this cursor for parsing, executing, and fetching |
OUTLINE_SID | VARCHAR2(40) | Outline session identifier |
LAST_ACTIVE_CHILD_ADDRESS | RAW(4) | Address (identifier) of the child cursor that was the last to be active in the group (that is, the child cursor on behalf of which statistics in V$SQL were updated) |
REMOTE | VARCHAR2(1) | Indicates whether the cursor is remote mapped (Y ) or not (N ) |
OBJECT_STATUS | VARCHAR2(19) | Status of the cursor:
|
LITERAL_HASH_VALUE | NUMBER | Hash value of the literals which are replaced with system-generated bind variables and are to be matched, whenCURSOR_SHARING is used. This is not the hash value for the SQL statement. If CURSOR_SHARING is not used, then the value is 0. |
LAST_LOAD_TIME | DATE | Time at which the query plan (heap 6) was loaded into the library cache |
IS_OBSOLETE | VARCHAR2(1) | Indicates whether the cursor has become obsolete (Y ) or not (N ). This can happen if the number of child cursors is too large. |
CHILD_LATCH | NUMBER | Child latch number that is protecting the cursor |
SQL_PROFILE | VARCHAR2(64) | SQL profile |
PROGRAM_ID | NUMBER | Program identifier |
PROGRAM_LINE# | NUMBER | Program line number |
EXACT_MATCHING_SIGNATURE | NUMBER | The signature used when the CURSOR_SHARING parameter is set to EXACT |
FORCE_MATCHING_SIGNATURE | NUMBER | The signature used when the CURSOR_SHARING parameter is set to FORCE |
LAST_ACTIVE_TIME | DATE | Time at which the query plan was last active |
BIND_DATA | RAW(2000) | Bind data |
http://www.oracle.com/technetwork/es/articles/sql/o29spm-098177-esa.html
Más sobre las estadísticas...
http://cajondesastreoracle.wordpress.com/category/oracle/estadisticas/
Estadísticas de segmentos de la base de datos
Como manejar de forma efectiva la recolección de estadísticas de segmentos de la base de datos
Las estadísticas son una colección de datos que describe en detalle a la base de datos y a cada uno de sus objetos. Son utilizadas por el optimizador para escoger el mejor plan de ejecución posible para cada sentencia. Estas estadísticas se usan para propósitos de optimización de consultas y no tienen relación con las estadísticas de performance visibles desde las vistas V$. Se almacenan en el catalogo de la base y entre la información que describen esta la siguiente:
Estadísticas de Tabla
Numero de Filas
Numero de Bloques
Largo Promedio de Fila
Estadísticas de Columna
Numero de valores distintos de la columna (selectividad)
Numero de nulos en la columna
Distribución de los datos (histogramas)
Estadísticas de Índice
Numero de bloques hoja
Niveles
Factor de Agrupamiento (Clustering Factor)
Estadísticas de Sistema
Utilización y Rendimiento de I/O
Utilización y Rendimiento de CPU's
Debido a que los objetos de la base de datos van cambiando las estadísticas deben ser mantenidas regularmente para así evitar el uso de planes erróneos basados en información desactualizada.
Recolección de Estadísticas Automática
Oracle Corporation recomienda que la recolección de estadísticas sea automática (default desde 10g) para así evitar que queden objetos sin estadísticas o con estadísticas desactualizadas. Este tipo de tareas automáticas, entre otras, se ejecutan dentro de las ventanas de mantenimiento predefinidas inicialmente. Si es necesario recolectar estadísticas en forma manual se debera invocar el paquete DBMS_STATS.
La job GATHER_STATS_JOB es creado automaticamente cuando se crea la base de datos y es manejado por el Scheduler. El Scheduler corre el job cuando la ventana de mantenimiento esta abierta (10pm a 6am de lunes a viernes y durante todo el dia el fin de semana).
El job GATHER_STATS_JOB llama al paquete interno DBMS_STATS.GATHER_DATABASE_STATS_JOBS_PROC que recolecta estadísticas de todos los objetos que no tuvieran ninguna estadística anteriormente y de aquellos objetos que hayan sido modificados significativamente (mas del 10% de las filas). La recolección de estadísticas se realiza primero sobre los objetos que mas cambiaron, fijando asi un esquema de prioridades que garantiza que los objetos con mas necesidad de renovación de estadísticas se actualicen dentro de la ventana de mantenimiento. Con la configuración default, de ser necesario, se continua analizando objetos luego de cerrada la ventana de mantenimiento.
Como verificar si se están recolectando las estadísticas en forma automática
Para asegurarse que se estén recolectando las estadísticas automáticamente chequear:
Que el job que corre las estadisticas este activo:
SELECT * FROM DBA_SCHEDULER_JOBS WHERE JOB_NAME = 'GATHER_STATS_JOB';
Que el monitor de modificaciones este activo:
Verificar que el parámetro STATISTICS_LEVEL se igual a TYPICAL ó ALL
Consideraciones para la recolección de estadísticas
Cuando utilizar estadísticas manuales
La recolección automática deberia ser adecuada para la mayoria de los objetos con un ratio de modificacion moderado. Debido a que el analisis de los objetos se realiza una vez por dia durante la ventana de mantenimiento, que generalmente es por la noche, a veces esta frecuencia no es suficiente para los objetos que sufren muchos cambios en el mismo dia ya que tienen que esperar que se abra la ventana de mantenimiento y por ende los objetos quedan desactualizados rapidamente. Existen dos tipos de objetos con dichas caracteristicas:
• Tablas volatiles que se borran o se truncan y que se vuelven a llenar durante el dia.
• Objetos que sufren cargas masivas que superan el 10% del tamaño total del objeto.
Enfoque de solución para tablas volátiles
• Se puede setear las estadísticas en null. Cuando el optimizador se encuentra con una tabla sin estadísticas dinámicamente obtiene las estadísticas necesarias como parte de la optimización. Este muestreo dinámico es gobernado por el parámetro OPTIMIZER_DYNAMIC_SAMPLING. El valor por default es 2 y no debería ser menor al default.
Para dejar las estadísticas nulas en una tabla hay que borrarlas y luego bloquearlas.
Por ejemplo, si quisieramos que al tabla ROP.T no tuviera estadísticas nunca hacemos:
begin
dbms_stats.delete_table_stats('ROP','T');
dbms_stats.lock_table_stats('ROP',''T');
end;
• Las estadísticas se podrían setear a valores que representen el estado típico de la tabla. Para implementarlo se deberá recolectar estadísticas en el momento mas adecuado y luego bloquear las estadísticas de la tabla en cuestión.
Enfoque de solución para objetos con carga masiva
• Para tablas con carga masiva las estadísticas deberán recolectarse inmediatamente luego de la carga. Es recomendable que la sentencia de actualización de estadísticas sean parte del script o proceso de carga.
• Los procesos automáticos de recolección de estadísticas no consideran las tablas externas. Para analizar este tipo de tablas habrá que hacerlo manualmente y cada vez que hay cambios sustanciales en el archivo que define la tabla externa.
• Las estadísticas de sistema no son analizadas automáticamente y deben ser analizadas manualmente. Se recomienda recolectar estadísticas de sistema para así darle mas información al optimizador.
Recolección manual de Estadísticas
Si por algún motivo se deshabilita la recolección automática se requerirá la recolección manual usando el paquete predefinido DBMS_STATS. Este paquete también permite modificar,ver, exportar, importar, setear y borrar estadísticas.
DBMS_STATS puede recolectar estadísticas de tablas, índices, columnas individuales y particiones. Cuando se generan estadísticas para una tabla, columna o índice y el diccionario de datos ya posee estadísticas para el objeto en cuestión Oracle modifica los valores existentes pero permite, de ser necesario en el futuro, los valores anteriores.
Cuando se actualizan las estadísticas para un objeto dado, Oracle invalida cualquier sentencia que estuvieran parseada y que referencie al objeto analizado. La próxima vez que se ejecute la sentencia ser va a reparsear. El optimizador podría elegir un nuevo plan basado en las nuevas estadísticas recolectadas. Las sentencias distribuidas que referencien objetos remotos con recolección de estadísticas reciente no se invalidaran. Las nuevas estadísticas no tomaran efecto hasta que la sentencia se vuelva a parsear.
Los procedimientos de DBMS_STATS para recolectar estadísticas son:
GATHER_INDEX_STATS : Estadísticas para índice
GATHER_TABLE_STATS : Estadísticas para tabla, índice y columna.
GATHER_SCHEMA_STATS : Estadísticas para todos los objetos del esquema.
GATHER_DICTIONARY_STATS : Estadísticas para todos los objetos del diccionario.
GATHER_DATABASE_STATS : Estadísticas para todos los objetos de la base de datos.
Recolección de estadísticas utilizando el paquete DBMS_STATS
• Recolección de estadísticas utilizando muestreo (sampling)
• Recolección de estadísticas en paralelo.
• Estadísticas sobre objetos particionados.
• Estadísticas de columnas e histogramas
• Como determinar estadísticas desactualizadas (stale)
Recolección de estadísticas utilizando muestreo (sampling)
Las operaciones de recolección de estadísticas pueden utilizar muestreo para estimar las estadísticas y de esta forma minimizar los recursos y el tiempo necesarios para el análisis ya que sin utilizar muestreo se debe hacer full scan y ordenamiento de las tablas enteras. El muestreo se especifica usando el argumento ESTIMATE_PERCENT en la invocación de paquete DBMS_STATS.
Oracle recomienda utilizar DBMS_STATS.AUTO_SAMPLE_SIZE para maximizar el rendimiento y al mismo tiempo obtener la precisión estadística mas adecuada. De esta forma se delega al motor de base de datos el calculo del porcentaje de filas a evaluar (muestreo) basado en las propiedades de cada objeto.
Cuando el parámetro ESTIMATE_PERCENT es especificado manualmente, los procedimientos de recolección de DBMS_STATS pueden incrementar el porcentaje de muestreo si el valor especificado no produjera un muestreo lo suficientemente grande.
Recolección de estadísticas en paralelo
Las operaciones de recolección de estadísticas pueden corren en serie o en paralelo. Le grado de paralelismo es expresado definiendo el parámetro DEGREE del paquete DBMS_STATS. Es recomendable utilizar la función DBMS_STATS.AUTO_DEGREE. De esta forma es Oracle el que elige el grado de paralelismo más apropiado basandose en el tamaño del objeto a analizar y en los parámetros de paralelismo definidos.
Estadísticas sobre objetos particionados
DBMS_STATS puede recolectar estadísticas en forma separada para subparticiones, particiones o estadísticas globales para una tabla o índice completos. El tipo de estadísticas para tablas particionadas se especifica por medio del parámetro GRANULARITY
Dependiendo del tipo de sentencia, el optimizador puede optar por usar estadísticas a nivel partición (o subpartición) o estadísticas de la tabla o índice completos. Es recomendable dejar el parámetro GRANULARITY seteado en AUTO que es el valor default ya que de esta forma Oracle determina la granularidad mas adecuada dependiendo del tipo de partición.
Estadísticas de columnas e histogramas
Cuando se recolectan estadísticas sobre una tabla se obtiene información de la distribución de datos de las columnas. Como información básica de la distribución se obtiene el valor mínimo y máximo pero esto no es suficiente si los datos en la columna son muy sesgados. Para valores no uniformes se necesitan histogramas que describen la distribución de los datos para una columna dada. Los histogramas se generan seteando el parámetro METHOD_OPT en los procedimientos de recolección (gather_xxx_stats) del paquete DBMS_STATS. Oracle recomienda setear el parámetro METHOD_OPT a "for all columns size auto" con lo cual se determina automáticamente que columna necesita histograma y se define el tamaño de "bucket".
Como determinar si las estadísticas están desactualizadas (stale)
Para determinar si un objeto esta necesitando nuevas estadísticas, Oracle provee un mecanismo de monitoreo que es habilitado por default cuando el parámetro STATISTICS_LEVEL esta configurado en TYPICAL o ALL. La información de los cambios (INSERT/UPDATE/DELETE) sobre las tablas se almacena en la vista USER_TAB_MODIFICATIONS.
Si las tablas monitoreadas fueron modificadas en mas del 10% del total de sus filas entonces sus estadísticas son consideradas STALE y serán analizadas la próxima vez que se ejecuten los procedimientos de DBMS_STATS: GATHER_DATABASE_STATS o GATHER_SCHEMA_STATS que definan el parámetro options como GATHER STALE o GATHER AUTO.
Estadísticas de Sistema
Las estadísticas de sistema describen características de hardware tales como rendimiento y utilización de I/O y CPU. Esta información es analizada por el optimizador en la etapa de parsing de las sentencias. El optimizador analiza costos de i/o y cpu para cada sentencia y los utiliza como información adicional para elegir un mejor plan.
Hay dos opciones para recolectar estadísticas de sistema: 1) se analiza la actividad del sistema en un periodo de tiempo especifico (workload statistics) o 2) se simula carga de trabajo (noworkload statistics). El procedimiento utilizado para recolectar estadísticas de sistema es DBMS_SPACE.GATHER_SYSTEM_STATS y se necesitan privilegios de DBA para ejecutarlo.
A diferencia de las estadísticas de tablas, índices o columnas, Oracle no invalida las sentencias que ya están parseadas cuando se actualizan las estadísticas de sistema. Las nuevas estadísticas si serán consideradas por las nuevas sentencias parseadas.
Oracle ofrece dos opciones para recolectar estadísticas de sistema:
• Workload Statistics
• NoWorkload Statistics
Workload Statistics
Las estadisticas de carga (workload statistics) fueron introducidas en 9i y recolectan: single read time (sreadtim) y multiblock read time (mreadtim), mbcr, CPU speed, maximum system throughput y average slave throughput. Los valores de sreadtim, mreadtim y mbcr son obtenidos comparando el número de lecturas físicas secuenciales y random entre dos puntos en el tiempo comprendidos entre el principio y el final del intervalo de workload. Las estadísticas de carga dependerán de la actividad que tuvo el sistema durante el periodo de muestra. Si ,por ejemplo, en la muestra se detecta un bajo rendimiento de i/o, se reflejará en las estadísticas y se promoverán planes de ejecución que contemplen menos i/o.
Para recolectar las estadísticas de sistema usar:
Para comenzar a medir ejecutar: Dbms_stats.gather_system_stats(‘start’)
Para finalizar de medir ejecutar : Dbms_stats.gather_system_stats(‘stop’)
ó
Correr dbms_stats.gather_system_stats(‘interval’,interval=>N), donde N es el número de minutos del muestreo.
Para eliminar las estadísticas correr: dbms_stats.delete_system_stats(). Esto borrará las estadísticas de carga y volverá a las estadísticas default (noworkload).
NoWorkload Statistics
La principal diferencia entre workload statistics y noworkload statistics reside en el método utilizado para la obtención de las estadísticas. Este tipo de estadísticas se toma generando lecturas random sobre todos los datafiles al contrario de la toma de estadísticas workload que utilizan contadores que se van actualizando con actividad real de la base de datos. La estadísticas noworkload consisten de i/o transfer speed, i/o seek time, y cpu speed. Oracle utiliza por default valores conservadores para setear la velocidad de i/o. Los variables y sus valores configurados en el primer startup de la base son:
ioseektim = 10ms
iotrfspeed = 4096 bytes/ms
cpuspeednw =
Para recolectar las estadísticas noworkload en forma manual hay que ejecutar: dbms_stats.gather_system_stats(), sin ningún argumento. La recolección puede variar en tiempo de acuerdo a la i/o del sistema y al tamaño de la base de datos. Si se recolectan estadísticas workload las estadísticas noworkload serán ignoradas y no se utilizaran en el futuro.
Vistas donde se almacenan estadísticas
Las estadísticas se guardan en el catalogo de la base y pueden ser consultadas desde las siguientes vistas:
[USER | ALL | DBA]_TABLES
[USER | ALL | DBA]_OBJECT_TABLES
[USER | ALL | DBA]_TAB_STATISTICS
[USER | ALL | DBA]_TAB_COL_STATISTICS
[USER | ALL | DBA]_TAB_HISTOGRAMS
[USER | ALL | DBA]_INDEXES
[USER | ALL | DBA]_IND_STATISTICS
[USER | ALL | DBA]_CLUSTERS
[USER | ALL | DBA]_TAB_PARTITIONS
[USER | ALL | DBA]_TAB_SUBPARTITIONS
[USER | ALL | DBA]_PART_COL_STATISTICS
[USER | ALL | DBA]_PART_HISTOGRAMS
[USER | ALL | DBA]_SUBPART_COL_STATISTICS
[USER | ALL | DBA]_SUBPART_HISTOGRAMS
Estadísticas de Tabla
Numero de Filas
Numero de Bloques
Largo Promedio de Fila
Estadísticas de Columna
Numero de valores distintos de la columna (selectividad)
Numero de nulos en la columna
Distribución de los datos (histogramas)
Estadísticas de Índice
Numero de bloques hoja
Niveles
Factor de Agrupamiento (Clustering Factor)
Estadísticas de Sistema
Utilización y Rendimiento de I/O
Utilización y Rendimiento de CPU's
Debido a que los objetos de la base de datos van cambiando las estadísticas deben ser mantenidas regularmente para así evitar el uso de planes erróneos basados en información desactualizada.
Recolección de Estadísticas Automática
Oracle Corporation recomienda que la recolección de estadísticas sea automática (default desde 10g) para así evitar que queden objetos sin estadísticas o con estadísticas desactualizadas. Este tipo de tareas automáticas, entre otras, se ejecutan dentro de las ventanas de mantenimiento predefinidas inicialmente. Si es necesario recolectar estadísticas en forma manual se debera invocar el paquete DBMS_STATS.
La job GATHER_STATS_JOB es creado automaticamente cuando se crea la base de datos y es manejado por el Scheduler. El Scheduler corre el job cuando la ventana de mantenimiento esta abierta (10pm a 6am de lunes a viernes y durante todo el dia el fin de semana).
El job GATHER_STATS_JOB llama al paquete interno DBMS_STATS.GATHER_DATABASE_STATS_JOBS_PROC que recolecta estadísticas de todos los objetos que no tuvieran ninguna estadística anteriormente y de aquellos objetos que hayan sido modificados significativamente (mas del 10% de las filas). La recolección de estadísticas se realiza primero sobre los objetos que mas cambiaron, fijando asi un esquema de prioridades que garantiza que los objetos con mas necesidad de renovación de estadísticas se actualicen dentro de la ventana de mantenimiento. Con la configuración default, de ser necesario, se continua analizando objetos luego de cerrada la ventana de mantenimiento.
Como verificar si se están recolectando las estadísticas en forma automática
Para asegurarse que se estén recolectando las estadísticas automáticamente chequear:
Que el job que corre las estadisticas este activo:
SELECT * FROM DBA_SCHEDULER_JOBS WHERE JOB_NAME = 'GATHER_STATS_JOB';
Que el monitor de modificaciones este activo:
Verificar que el parámetro STATISTICS_LEVEL se igual a TYPICAL ó ALL
Consideraciones para la recolección de estadísticas
Cuando utilizar estadísticas manuales
La recolección automática deberia ser adecuada para la mayoria de los objetos con un ratio de modificacion moderado. Debido a que el analisis de los objetos se realiza una vez por dia durante la ventana de mantenimiento, que generalmente es por la noche, a veces esta frecuencia no es suficiente para los objetos que sufren muchos cambios en el mismo dia ya que tienen que esperar que se abra la ventana de mantenimiento y por ende los objetos quedan desactualizados rapidamente. Existen dos tipos de objetos con dichas caracteristicas:
• Tablas volatiles que se borran o se truncan y que se vuelven a llenar durante el dia.
• Objetos que sufren cargas masivas que superan el 10% del tamaño total del objeto.
Enfoque de solución para tablas volátiles
• Se puede setear las estadísticas en null. Cuando el optimizador se encuentra con una tabla sin estadísticas dinámicamente obtiene las estadísticas necesarias como parte de la optimización. Este muestreo dinámico es gobernado por el parámetro OPTIMIZER_DYNAMIC_SAMPLING. El valor por default es 2 y no debería ser menor al default.
Para dejar las estadísticas nulas en una tabla hay que borrarlas y luego bloquearlas.
Por ejemplo, si quisieramos que al tabla ROP.T no tuviera estadísticas nunca hacemos:
begin
dbms_stats.delete_table_stats('ROP','T');
dbms_stats.lock_table_stats('ROP',''T');
end;
• Las estadísticas se podrían setear a valores que representen el estado típico de la tabla. Para implementarlo se deberá recolectar estadísticas en el momento mas adecuado y luego bloquear las estadísticas de la tabla en cuestión.
Enfoque de solución para objetos con carga masiva
• Para tablas con carga masiva las estadísticas deberán recolectarse inmediatamente luego de la carga. Es recomendable que la sentencia de actualización de estadísticas sean parte del script o proceso de carga.
• Los procesos automáticos de recolección de estadísticas no consideran las tablas externas. Para analizar este tipo de tablas habrá que hacerlo manualmente y cada vez que hay cambios sustanciales en el archivo que define la tabla externa.
• Las estadísticas de sistema no son analizadas automáticamente y deben ser analizadas manualmente. Se recomienda recolectar estadísticas de sistema para así darle mas información al optimizador.
Recolección manual de Estadísticas
Si por algún motivo se deshabilita la recolección automática se requerirá la recolección manual usando el paquete predefinido DBMS_STATS. Este paquete también permite modificar,ver, exportar, importar, setear y borrar estadísticas.
DBMS_STATS puede recolectar estadísticas de tablas, índices, columnas individuales y particiones. Cuando se generan estadísticas para una tabla, columna o índice y el diccionario de datos ya posee estadísticas para el objeto en cuestión Oracle modifica los valores existentes pero permite, de ser necesario en el futuro, los valores anteriores.
Cuando se actualizan las estadísticas para un objeto dado, Oracle invalida cualquier sentencia que estuvieran parseada y que referencie al objeto analizado. La próxima vez que se ejecute la sentencia ser va a reparsear. El optimizador podría elegir un nuevo plan basado en las nuevas estadísticas recolectadas. Las sentencias distribuidas que referencien objetos remotos con recolección de estadísticas reciente no se invalidaran. Las nuevas estadísticas no tomaran efecto hasta que la sentencia se vuelva a parsear.
Los procedimientos de DBMS_STATS para recolectar estadísticas son:
GATHER_INDEX_STATS : Estadísticas para índice
GATHER_TABLE_STATS : Estadísticas para tabla, índice y columna.
GATHER_SCHEMA_STATS : Estadísticas para todos los objetos del esquema.
GATHER_DICTIONARY_STATS : Estadísticas para todos los objetos del diccionario.
GATHER_DATABASE_STATS : Estadísticas para todos los objetos de la base de datos.
Recolección de estadísticas utilizando el paquete DBMS_STATS
• Recolección de estadísticas utilizando muestreo (sampling)
• Recolección de estadísticas en paralelo.
• Estadísticas sobre objetos particionados.
• Estadísticas de columnas e histogramas
• Como determinar estadísticas desactualizadas (stale)
Recolección de estadísticas utilizando muestreo (sampling)
Las operaciones de recolección de estadísticas pueden utilizar muestreo para estimar las estadísticas y de esta forma minimizar los recursos y el tiempo necesarios para el análisis ya que sin utilizar muestreo se debe hacer full scan y ordenamiento de las tablas enteras. El muestreo se especifica usando el argumento ESTIMATE_PERCENT en la invocación de paquete DBMS_STATS.
Oracle recomienda utilizar DBMS_STATS.AUTO_SAMPLE_SIZE para maximizar el rendimiento y al mismo tiempo obtener la precisión estadística mas adecuada. De esta forma se delega al motor de base de datos el calculo del porcentaje de filas a evaluar (muestreo) basado en las propiedades de cada objeto.
Cuando el parámetro ESTIMATE_PERCENT es especificado manualmente, los procedimientos de recolección de DBMS_STATS pueden incrementar el porcentaje de muestreo si el valor especificado no produjera un muestreo lo suficientemente grande.
Recolección de estadísticas en paralelo
Las operaciones de recolección de estadísticas pueden corren en serie o en paralelo. Le grado de paralelismo es expresado definiendo el parámetro DEGREE del paquete DBMS_STATS. Es recomendable utilizar la función DBMS_STATS.AUTO_DEGREE. De esta forma es Oracle el que elige el grado de paralelismo más apropiado basandose en el tamaño del objeto a analizar y en los parámetros de paralelismo definidos.
Estadísticas sobre objetos particionados
DBMS_STATS puede recolectar estadísticas en forma separada para subparticiones, particiones o estadísticas globales para una tabla o índice completos. El tipo de estadísticas para tablas particionadas se especifica por medio del parámetro GRANULARITY
Dependiendo del tipo de sentencia, el optimizador puede optar por usar estadísticas a nivel partición (o subpartición) o estadísticas de la tabla o índice completos. Es recomendable dejar el parámetro GRANULARITY seteado en AUTO que es el valor default ya que de esta forma Oracle determina la granularidad mas adecuada dependiendo del tipo de partición.
Estadísticas de columnas e histogramas
Cuando se recolectan estadísticas sobre una tabla se obtiene información de la distribución de datos de las columnas. Como información básica de la distribución se obtiene el valor mínimo y máximo pero esto no es suficiente si los datos en la columna son muy sesgados. Para valores no uniformes se necesitan histogramas que describen la distribución de los datos para una columna dada. Los histogramas se generan seteando el parámetro METHOD_OPT en los procedimientos de recolección (gather_xxx_stats) del paquete DBMS_STATS. Oracle recomienda setear el parámetro METHOD_OPT a "for all columns size auto" con lo cual se determina automáticamente que columna necesita histograma y se define el tamaño de "bucket".
Como determinar si las estadísticas están desactualizadas (stale)
Para determinar si un objeto esta necesitando nuevas estadísticas, Oracle provee un mecanismo de monitoreo que es habilitado por default cuando el parámetro STATISTICS_LEVEL esta configurado en TYPICAL o ALL. La información de los cambios (INSERT/UPDATE/DELETE) sobre las tablas se almacena en la vista USER_TAB_MODIFICATIONS.
Si las tablas monitoreadas fueron modificadas en mas del 10% del total de sus filas entonces sus estadísticas son consideradas STALE y serán analizadas la próxima vez que se ejecuten los procedimientos de DBMS_STATS: GATHER_DATABASE_STATS o GATHER_SCHEMA_STATS que definan el parámetro options como GATHER STALE o GATHER AUTO.
Estadísticas de Sistema
Las estadísticas de sistema describen características de hardware tales como rendimiento y utilización de I/O y CPU. Esta información es analizada por el optimizador en la etapa de parsing de las sentencias. El optimizador analiza costos de i/o y cpu para cada sentencia y los utiliza como información adicional para elegir un mejor plan.
Hay dos opciones para recolectar estadísticas de sistema: 1) se analiza la actividad del sistema en un periodo de tiempo especifico (workload statistics) o 2) se simula carga de trabajo (noworkload statistics). El procedimiento utilizado para recolectar estadísticas de sistema es DBMS_SPACE.GATHER_SYSTEM_STATS y se necesitan privilegios de DBA para ejecutarlo.
A diferencia de las estadísticas de tablas, índices o columnas, Oracle no invalida las sentencias que ya están parseadas cuando se actualizan las estadísticas de sistema. Las nuevas estadísticas si serán consideradas por las nuevas sentencias parseadas.
Oracle ofrece dos opciones para recolectar estadísticas de sistema:
• Workload Statistics
• NoWorkload Statistics
Workload Statistics
Las estadisticas de carga (workload statistics) fueron introducidas en 9i y recolectan: single read time (sreadtim) y multiblock read time (mreadtim), mbcr, CPU speed, maximum system throughput y average slave throughput. Los valores de sreadtim, mreadtim y mbcr son obtenidos comparando el número de lecturas físicas secuenciales y random entre dos puntos en el tiempo comprendidos entre el principio y el final del intervalo de workload. Las estadísticas de carga dependerán de la actividad que tuvo el sistema durante el periodo de muestra. Si ,por ejemplo, en la muestra se detecta un bajo rendimiento de i/o, se reflejará en las estadísticas y se promoverán planes de ejecución que contemplen menos i/o.
Para recolectar las estadísticas de sistema usar:
Para comenzar a medir ejecutar: Dbms_stats.gather_system_stats(‘start’)
Para finalizar de medir ejecutar : Dbms_stats.gather_system_stats(‘stop’)
ó
Correr dbms_stats.gather_system_stats(‘interval’,interval=>N), donde N es el número de minutos del muestreo.
Para eliminar las estadísticas correr: dbms_stats.delete_system_stats(). Esto borrará las estadísticas de carga y volverá a las estadísticas default (noworkload).
NoWorkload Statistics
La principal diferencia entre workload statistics y noworkload statistics reside en el método utilizado para la obtención de las estadísticas. Este tipo de estadísticas se toma generando lecturas random sobre todos los datafiles al contrario de la toma de estadísticas workload que utilizan contadores que se van actualizando con actividad real de la base de datos. La estadísticas noworkload consisten de i/o transfer speed, i/o seek time, y cpu speed. Oracle utiliza por default valores conservadores para setear la velocidad de i/o. Los variables y sus valores configurados en el primer startup de la base son:
ioseektim = 10ms
iotrfspeed = 4096 bytes/ms
cpuspeednw =
Para recolectar las estadísticas noworkload en forma manual hay que ejecutar: dbms_stats.gather_system_stats(), sin ningún argumento. La recolección puede variar en tiempo de acuerdo a la i/o del sistema y al tamaño de la base de datos. Si se recolectan estadísticas workload las estadísticas noworkload serán ignoradas y no se utilizaran en el futuro.
Vistas donde se almacenan estadísticas
Las estadísticas se guardan en el catalogo de la base y pueden ser consultadas desde las siguientes vistas:
[USER | ALL | DBA]_TABLES
[USER | ALL | DBA]_OBJECT_TABLES
[USER | ALL | DBA]_TAB_STATISTICS
[USER | ALL | DBA]_TAB_COL_STATISTICS
[USER | ALL | DBA]_TAB_HISTOGRAMS
[USER | ALL | DBA]_INDEXES
[USER | ALL | DBA]_IND_STATISTICS
[USER | ALL | DBA]_CLUSTERS
[USER | ALL | DBA]_TAB_PARTITIONS
[USER | ALL | DBA]_TAB_SUBPARTITIONS
[USER | ALL | DBA]_PART_COL_STATISTICS
[USER | ALL | DBA]_PART_HISTOGRAMS
[USER | ALL | DBA]_SUBPART_COL_STATISTICS
[USER | ALL | DBA]_SUBPART_HISTOGRAMS
viernes, 7 de junio de 2013
sinonimos
DROP PUBLIC SYNONYM tabla_sinonimo1;
DROP PUBLIC SYNONYM tabla_sinonimo2;
DROP PUBLIC SYNONYM tabla_sinonimo3;
DROP PUBLIC SYNONYM tabla_sinonimo4;
COMMIT;
CREATE PUBLIC SYNONYM tabla_sinonimo1 FOR esquema1.tabla1;
CREATE PUBLIC SYNONYM tabla_sinonimo2 FOR esquema1.tabla2;
COMMIT:
-------------------------
Pueden estar mal generados sin embargo:
SELECT ' *
FROM ALL_TABLES WHERE OWNER in ('esquema1','esquema2', 'esquema3','esquema4', 'esquema5','esquema6')
AND TABLE_NAME='tabla1'
select *
from DBA_synonyms where
--TABLE_OWNER in ('esquema1','esquema6', 'esquema2','esquema3', 'esquema4','esquema5')
-- AND
TABLE_NAME='tab'le1
--- LOS BUSCAMOS COMO TABLAS
-- PARA VER SU ESQUEMA
SELECT * FROM ALL_TABLES WHERE TABLE_NAME = 'table1' UNION
SELECT * FROM ALL_TABLES WHERE TABLE_NAME = 'table2' UNION
SELECT * FROM ALL_TABLES WHERE TABLE_NAME = 'table3' UNION
SELECT * FROM ALL_TABLES WHERE TABLE_NAME = 'table4' UNION
SELECT * FROM ALL_TABLES WHERE TABLE_NAME = 'table5' UNION
SELECT * FROM ALL_TABLES WHERE TABLE_NAME = 'table6' UNION
SELECT * FROM ALL_TABLES WHERE TABLE_NAME = 'table7' UNION
SELECT * FROM ALL_TABLES WHERE TABLE_NAME = 'table8' UNION
ORDER BY 2,1
-------------------------------------------------
ALTER TABLE esquema1.tabla1MOVE TABLESPACE tbspace1;
--------------------------------
SELECT * FROM dba_objects WHERE status = 'INVALID'
SELECT DISTINCT owner FROM all_synonyms;
SELECT * FROM all_synonyms;
-------------------------------
select s.TABLE_OWNER, count(*)Cantidad from all_synonyms s
where not exists(select 1 from all_objects o where s.TABLE_OWNER=o.OWNER and s.TABLE_NAME=o.OBJECT_NAME )
and owner not in ('SYS','SYSTEM')
group by s.TABLE_OWNER;
SELECT * FROM USER_synonyms;
SELECT sy.OWNER, sy.SYNONYM_NAME, sy.TABLE_OWNER, sy.TABLE_NAME, ta.TABLESPACE_NAME
FROM user_tables ta, all_synonyms sy
WHERE ta.TABLE_NAME = sy.TABLE_NAME
SELECT sy.SYNONYM_NAME, sy.TABLE_OWNER, sy.TABLE_NAME, ta.TABLESPACE_NAME
FROM user_tables ta, user_synonyms sy
WHERE ta.TABLE_NAME = sy.TABLE_NAME
SELECT * FROM dba_synonyms
SELECT * FROM ALL_TABLES;
--- ==============================
--- &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
SELECT 'CREATE PUBLIC SYNONYM '
|| synonym_name
|| ' FOR '
|| table_owner
|| '.'
|| table_name
|| ';'
FROM dba_synonyms
WHERE TABLE_OWNER = 'esquema1' OR TABLE_OWNER = 'esquema2' OR TABLE_OWNER = 'esquema3'
OR TABLE_OWNER = 'esquema4' OR TABLE_OWNER = 'esquema5' OR TABLE_OWNER = 'esquema6'
select 'CREATE SYNONYM '||SYNONYM_NAME||' FOR '||TABLE_OWNER||'.'||TABLE_NAME||';'
from DBA_synonyms where TABLE_OWNER in ('esquema1','esquema2');
En cada esquema de origen en la BD de origen ejecutar las siguientes querys:
Sinónimos:
select 'CREATE SYNONYM '||SYNONYM_NAME||' FOR '||TABLE_OWNER||'.'||TABLE_NAME||';' from user_synonyms where TABLE_OWNER in ('UN_ESQUEMA','OTRO_ESQUEMA');
Privilegios:
select 'GRANT '||PRIVILEGE||' ON '||TABLE_NAME||' TO '||GRANTEE||';' from all_tab_privs_made where GRANTOR='MI_ESQUEMA' and GRANTEE='OTROS_ESQUEMAS';
Secuencias:
select 'CREATE SEQUENCE '||sequence_name||' START WITH '||to_char(last_number+1)||';' from user_sequences order by sequence_name;
replace public synonym suppliers
for app.suppliers;
drop [public] synonym [schema .] synonym_name [force];
CREATE PUBLIC SYNONYM WCTG_REG FOR CB_CVP_001.WCTG_REG;
Drop PUBLIC SYNONYM WCTG_REG;
ROLLBACK;
select ' DROP PUBLIC SYNONYM '||SYNONYM_NAME||';'
from DBA_synonyms where TABLE_OWNER in ('esquema1','esquema2', 'esquema3','esquema4', 'esquema5' );
select ' CREATE PUBLIC SYNONYM '||SYNONYM_NAME||' FOR '||TABLE_OWNER||'.'||TABLE_NAME||';'
from DBA_synonyms where TABLE_OWNER in ('esquema1');
select ' CREATE PUBLIC SYNONYM '||SYNONYM_NAME||' FOR '||TABLE_OWNER||'.'||TABLE_NAME||';'
from DBA_synonyms where TABLE_OWNER in ('esquema1','esquema2', 'esquema4','esquema5', 'esquema6' );
-- WHERE TABLE_OWNER = 'esquema1' OR TABLE_OWNER = 'esquema2' OR TABLE_OWNER = 'esquema3'
-- OR TABLE_OWNER = 'esquema4' OR TABLE_OWNER = 'esquema5' OR TABLE_OWNER = 'esquema6'
SELECT * from DBA_synonyms;
-- REPLACE PUBLIC SYNONYM tabla1 FOR esquema1.tabla1;
SELECT * FROM dba_objects --WHERE OBJECT_NAME = 'tabla1' AND OBJECT_TYPE ='SYNONYM'
where status = 'INVALID'
Suscribirse a:
Entradas (Atom)