¿Cómo borrar un histograma sobre una columna? De manera muy genérica podemos decir que una base de datos relacional se basa mayormente en la teoría de conjuntos y en modelos estadísticos. La teoría de conjuntos en una base de datos generará los resultados correctos mientras que los modelos estadísticos servirán para que la respuesta solicitada se resuelva rápido.
El tema con las estadísticas no es tener estadísticas, ni siquiera tener estadísticas actualizadas. Estamos hablando de modelos estadísticos por lo que lo importante es tener el modelo correcto, es decir, las estadísticas con los valores correctos. Para lograrlo puede optarse por cualquiera de las siguientes
- borrar estadísticas,
- generar estadísticas,
- haquear estadísticas,
Cuando digo “haquear” estadísticas significa establecer valores en forma manual para que el modelo sea representado de forma más acertada con las estadísticas.
En una ocasión un administrador insistía muchísimo en generar estadísticas e histogramas para todas las tablas y columnas de la base de datos. A pesar de haberle advertido que no lo hiciera, lo hizo. ¿Cuál fue el resultado? una catástrofe, los tiempos de respuesta se dispararon y la toma de estadísticas duró más de dos días sin que terminara el proceso. Por ahora no explicaré las razones pues ya será tema de otro post hablar sobre los tipos de estadísticas, cuándo y por qué obtenerlas. Por lo pronto quiero resolver la pregunta
¿cómo borrar un histograma sobre una columna?
Dado que los histogramas son percentiles (Oracle Corporation los llama cubetas, aunque un percentil no tiene nada que ver con una cubeta), se necesita tener al menos dos percentiles para poder generar un histograma. Así que si generamos un histograma con tamaño 1 es realmente borrar el histograma previo. Si anteriormente no había ningún histograma entonces Oracle generará datos en el diccionario donde diga que alguna vez se le generó un histograma a la columna de la tabla en cuestión.
La sentencia es
exec dbms_stats.gather_table_stats(ownname => 'owner', tabname => 'table', method_opt => 'for columns column_name size 1');
Vamos a aclararlo con un ejemplo
Inicialmente tenemos una tabla llamada STAGE, y hacemos al diccionario la consulta
select column_Name, num_distinct, density, num_nulls, histogram from dba_tab_columns where table_Name = 'STAGE';
COLUMN_NAME NUM_DISTINCT DENSITY NUM_NULLS HISTOGRAM
---------------- ------------- ---------- ------------ ----------
ID 0 0 0 NONE
OBJECT 0 0 0 NONE
TDATE 0 0 0 NONE
ID2 0 0 0 NONE
Tenemos entonces una tabla con 4 columnas donde no se han generado estadísticas de ningún tipo. Y lo podemos confirmar con la sentencia
select column_Name, num_distinct, density, num_nulls, histogram from user_tab_columns where table_Name = 'STAGE';
COLUMN_NAME NUM_DISTINCT DENSITY NUM_NULLS HISTOGRAM
---------------- ------------- ---------- ------------ ----------
ID 11374 .00008792 0 NONE
OBJECT 8732 .000114521 0 NONE
TDATE 497 .002012072 0 NONE
ID2 11374 .00008792 0 NONE
Ahora generamos un histograma con tamaño 11, es decir con 10 percentiles
exec dbms_stats.gather_table_stats(ownname => 'demo', tabname=> 'stage', method_opt => 'for columns object size 10');
Nuevamente validamos los valores que la generación del histograma ha modificado
COLUMN_NAME NUM_DISTINCT DENSITY NUM_NULLS HISTOGRAM
---------------- ------------- ---------- ------------ ----------
ID 11374 .00008792 0 NONE
OBJECT 8732 .000223714 0 HEIGHT BALANCED
TDATE 497 .002012072 0 NONE
ID2 11374 .00008792 0 NONE
Finalmente borramos el histograma sobre la columna object,
exec dbms_stats.gather_table_stats(ownname => 'demo', tabname=> 'stage', method_opt => 'for columns object size 1');
COLUMN_NAME NUM_DISTINCT DENSITY NUM_NULLS HISTOGRAM
---------------- ------------- ---------- ------------ ----------
ID 11374 .00008792 0 NONE
OBJECT 8732 .000114521 0 NONE
TDATE 497 .002012072 0 NONE
ID2 11374 .00008792 0 NONE
Y finalmente tenemos los valores iniciales. Quiero enfatizar que antes de generar el histograma se tenían estadísticas para la tabla y que cuando se generó el histograma las estadísticas se modificaron. El tener estadísticas actualizadas no significa que son las estadísticas que mejor modelen la distribución de los datos, al final, cuando eliminamos el histograma, las estadísticas volvieron a los valores iniciales.