Skip to main content

Command Palette

Search for a command to run...

Estadísticas. Probamos antes de actualizarlas?

Updated
2 min readView as Markdown
Estadísticas. Probamos antes de actualizarlas?
C

Mi nombre es Carla y me defino como una apasionada de conocer, compartir ideas, divertirme y aprender todo lo relacionado con Oracle.

Alegre y creativa, con un alto grado de autoexigencia, que busca, incluso sin querer, una forma diferente de ver un mismo problema o solución. Defensora del trabajo en equipo en todas las facetas de la vida y de disfrutar todo lo que haces, siempre con humildad.

Actualmente cuento con más de 15 años de experiencia como administradora de Oracle, habiendo ocupado previamente posiciones como desarrolladora en la rama de Inteligencia de Negocios. Fue en ese momento que me di cuenta de que no quería centrarme en el desarrollo, sino participar en todas las capas que involucraban los datos, desde el despliegue de la base de datos hasta su explotación final.

Siempre estoy dispuesta a ayudar y compartir conocimientos. Creo firmemente que con la tecnología hay que divertirse y no verla como una competencia. La persona con la que tienes que ser el mejor es contigo mismo.

Hay casos en los que existe temor a la hora de actualizar las estadísticas.

Normalmente son casos en los que llevan sin actualizarse meses, incluso años por miedo a éstas, o simplemente se quiere probar un cambio en concreto en relación a un plan de ejecución y se quiere ser cauto.

Para ello tenemos una opción muy interesante en Oracle que nos permite probar las estadísticas que queremos antes de verse reflejadas finalmente en los objetos.

¿En qué consiste el método? Básicamente pasaremos las estadísticas pero no las publicaremos ( no serán aún efectivas) pero podremos probar el impacto en el plan o los planes de ejecución que queramos validar antes de darles el ok.

Expongo el procedimiento para una tabla:

alter session set nls_date_format='dd/mm/yyyy hh24:mi:ss';
select table_name, last_analyzed,num_rows from dba_tables where owner='PRU' and table_name='TABLAPRU';

TABLE_NAME         LAST_ANALYZED         NUM_ROWS
------------------ ------------------- ----------
TABLAPRU           24/06/2023 22:07:59      11349


select count(*) from PRU.TABLAPRU; 

  COUNT(*)
----------
     12616

-- Deshabilitamos la publicación, para que no apliquen al ejecutarlas
select dbms_stats.get_prefs('PUBLISH', 'PRU', 'TABLAPRU' ) FROM DUAL;

DBMS_STATS.GET_PREFS('PUBLISH','PRU','TABLAPRU')                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
---------------------------------------------------
TRUE

exec dbms_stats.set_table_prefs('PRU','TABLAPRU','PUBLISH','FALSE');

PL/SQL procedure successfully completed.



select dbms_stats.get_prefs('PUBLISH', 'PRU', 'TABLAPRU' ) FROM DUAL;

DBMS_STATS.GET_PREFS('PUBLISH','PRU','TABLAPRU')                                                                                                                                                  
--------------------------------------------------------
FALSE

-- Ejecutamos estadísticas
exec DBMS_STATS.GATHER_TABLE_STATS (ownname => 'PRU' , tabname => 'TABLAPRU',cascade => true, estimate_percent => dbms_stats.auto_sample_size, method_opt=>'FOR ALL COLUMNS SIZE AUTO');
PL/SQL procedure successfully completed.



-- Comprobar que siguen intactas
select table_name, last_analyzed,num_rows from dba_tables where owner='PRU' and table_name='TABLAPRU';

TABLE_NAME        LAST_ANALYZED         NUM_ROWS
------------------------------------- ----------
TABLAPRU          24/06/2023 22:07:59      11349

-- Estadisticas pendientes
SELECT table_name, last_analyzed from DBA_TAB_PENDING_STATS where table_name='TABLAPRU';

TABLE_NAME         LAST_ANALYZED      
------------------ -------------------
TABLAPRU           07/11/2023 13:07:48

Probaríamos el plan o planes de ejecución que queremos validar con el cambio:

alter session set optimizer_use_pending_statistics=true;
select /*+ gather_plan_statistics */ 
from .....;

select * from table(dbms_xplan.display_cursor(format=>'basic +rows +rowstats last'));
alter session set optimizer_use_pending_statistics=false

Si lo damos por válido sólo nos quedaría publicarlas:

exec dbms_stats.publish_pending_stats('PRU','TABLAPRU',no_invalidate=>false);

En caso de necesitarlo recordar que se pueden recuperar del histórico. De igual manera siempre recomiendo hacer un backup previo de éstas (DBMS_STATS.EXPORT_SCHEMA_STATS)

exec dbms_stats.restore_table_stats('PRU','TABLAPRU',sysdate-1,no_invalidate=>false);

More from this blog

Carla Muñoz López

65 posts

Soy DBA senior de bases de datos Oracle y me defino como una persona alegre y creativa. Apasionada por conocer, compartir ideas, divertirme y seguir aprendiendo todo lo relacionado con Oracle.