Oracle dispone de herramientas que nos permiten
mejorar el rendimiento de la base de datos.
Las
estadísticas que Oracle tiene almacenadas tienen un impacto real en el "como" Oracle va a resolver nuestras consultas.
Cuando tenemos tablas y/o índices de un tamaño considerable, podemos notar un incremento en el tiempo de ejecución de las Querys, si las
estadísticas no están bien computadas.
No entraré en detalles técnicos porque realmente no los conozco todos, pero siendo práctico, en mi día a día, he notado mejoras considerables cuando las tablas y los índices han tenido las estadísticas bien computadas.
Lo primero que aprendí en el tema de analizar las tablas fue el comando
ANALYZE:
ANALYZE TABLE mi_tabla ESTIMATE STATISTICS SAMPLE 5 PERCENT;Con este comando analizo la tabla 'mi_tabla' estimando las estadísticas con un 5% de datos. Normalmente con está estimación ya es suficiente (un 5% de una tabla de millones de registros puede dar una idea bastante exacta de como están los datos)
Muchas veces puedes ver un
cambio en el plan de ejecución de Oracle antes y después de analizar las tablas implicadas en una consulta. Sobretodo si son tablas grandes o si han crecido respecto la última vez que se computaron estadísticas.
Ahora, con las nuevas versiones de Oracle utilizo el
DBMS_STATS.GATHER_TABLE_STATS un Procedure que permite analizar las estadísticas de las tablas, columnas e índices de manera más óptima.
Este proceso tiene más parámetros de los que voy a comentar, pero como siempre, me baso en lo que yo utilizo o he utilizado (El resto se puede consultar en la página de Oracle)
SYS.DBMS_STATS.GATHER_TABLE_STATS (
OwnName => 'usuario'
,TabName => 'mi_tabla'
,Estimate_Percent => 5
,Method_Opt => 'FOR ALL COLUMNS SIZE AUTO'
,Degree => 4
,Cascade => TRUE
);
- OwnName: Esquema dónde se encuentra la tabla a analizar.
- TabName: Nombre de la tabla a analizar.
- Estimate_Percent: Porcentaje de filas a estimar.El rango valido es de 0.000001 a 100.En este caso hemos utilizado un 5, o sea un 5%.Es más recomendable usar la constante DBMS_STATS.AUTO_SAMPLE_SIZE, para que el propio Oracle determine el porcentaje suficiente para obtener unas buenas estadísticas. Aunque la primera vez que se ejecuté puede tardar mucho.
- Method_Opt: Hemos utilizado el valor por defecto FOR ALL COLUMNS SIZE AUTO.
- Degree: Grado de paralelismo. Cuando ejecutamos el procedimiento en horario de oficina no utilizamos ningún paralelismo para no sobrecargar la máquina. Por la noche si que podemos usarlo, siempre bajo la aprobación del DBA.
- Cascade: Valor importante. TRUE indica que computamos también las estadísticas de todos los índices relacionados con esta tabla. Utilizar esta función es equivalente a utilizar la función GATHER_INDEX_STATS
Y aquí un ejemplo de función utilizada para computar las estadísticas de todas las tablas que empiezan por 'mi_%'.
FUNCTION fnt_analize RETURN NUMBER IS
CURSOR tablas IS
SELECT table_name FROM user_tables WHERE table_name LIKE 'mi_%';
V_USUARIO VARCHAR2(30);
BEGIN
SELECT user INTO V_USUARIO FROM dual;
FOR tabla IN tablas LOOP
SYS.DBMS_STATS.GATHER_TABLE_STATS (
OwnName => V_USUARIO
,TabName => tabla.TABLE_NAME
,Estimate_Percent => 5
,Method_Opt => 'FOR ALL COLUMNS SIZE AUTO '
,Cascade => TRUE
);
END LOOP;
RETURN 1;
EXCEPTION
WHEN OTHERS THEN
Dbms_Output.put_line(SQLERRM);
RETURN 3;
END fnt_analize;Normalmente es recomendable computar estadísticas cuando la tabla ha
variado considerablemente su tamaño (tanto si hemos realizado inserts como deletes).
Si estamos en un proceso de migración de datos, o cargas masivas dónde cargamos millones de registros diariamente, puede que sea recomendable analizar las tablas cada cierto período y no esperar a que se haya finalizado la migración/carga.