jueves, 13 de noviembre de 2008

Dimensionamiento de Esquemas de Datos (Sizing)

Muchas veces me han pedido realizar un dimensionamiento (sizing) de un esquema de base de datos. Es habitual que los dba's pidamos un detalle de tamaño actual y proyectado para así poder anticipar problemas de espacio, realizar pedidos de nuevo hardware con tiempo, anticipar carga de un equipo, etc.
Existen varias herramientas para estimar, se pueden usar productos como el TOAD, DbaArtisan, etc.
Yo propongo usar un metodo sencillo que solo y que no requiere ninguna herramienta de terceros, solo usando un script.Para ello se deberá crear una tabla con las siguientes columnas:

Table_name
num_rows
filas_crec_proyectada
periodo_crec_proyectado

La tabla se deberá completar con el detalle de las tablas con mas registros.
Las tablas involucradas deberán estar analizadas y con una cierta cantidad de filas con datos reales o similares. Cuanto mas representativos sean los datos iniciales mejor será la estimación.

Una vez creada esa tabla podemos usar el query de abajo que nos estimará el crecimiento a un 1 mes, 3 meses, 6 meses y 1 año.



-----------------------------------------------------------------------------
-- Script para dimensionar esquemas de datos --

set linesize 140
set pagesize 9999
set verify off

col "Periodo Crec. Proy." format a15
col Per_Proy format a12
col table_name format a30


PROMPT
PROMPT ***************************************
PROMPT LISTADO DE TABLAS DE LA APLICACION
PROMPT (ordenadas por cantidad de registros)
PROMPT ***************************************
PROMPT

select t1.table_name "Tabla",
t1.num_rows "Cant. de Filas Actual",
t2.filas_crec_proyectada "Filas Crec. Proy.",
t2.periodo_crec_proyectadorpad(' ',10) "Periodo Crec. Proy."
from user_tables t1,
tbl_sizing_config t2
where t1.table_name = t2.table_name
/


ACCEPT PctTabs PROMPT "Ingrese el porcentaje que representan las tablas a analizar sobre total [80]> "

declare
l_aloc_act int;
l_aloc_lob int;
l_aloc_idx int;
l_coef_ajuste int;
l_sum_pmes1 int;
l_sum_pmes3 int;
l_sum_pmes6 int;
l_sum_paño int;
begin
select sum(t1.bytes)
into l_aloc_idx
from user_segments t1,
user_indexes t2,
tbl_sizing_config t3
where t1.segment_name_name = t2.index_name
and t1.segment_type = 'INDEX'
and t2.table_name = t3.table_name;

select sum(t1.bytes)
into l_aloc_lob
from user_segments t1,
user_lobs t2,
tbl_sizing_config t3
where t1.segment_name_name = t2.segment_name
and t2.table_name = t3.table_name;
and t1.segment_type like 'LOB%';

l_coef_ajuste := l_aloc_indexes/l_aloc_tables +
l_aloc_lobs/l_aloc_tables + 1,15;

select sum(Aloc_Act),
sum("Proy 1Mes") PMes1,
sum("Proy 3Mes") PMes3,
sum("Proy 6Mes") PMes6,
sum("Proy 1Año") PAño
into l_aloc_act,l_sum_pmes1,l_sum_pmes3,l_sum_pmes6,l_sum_paño
from
(select t1.table_name,
t1.num_rows,
t2.tasa_crec_proyectada Tasa_Proy,
t2.periodo_crec_proyectado Periodo_Proy,
round(t3.bytes/1024/1024,2) Aloc_Act,
round((((t1.avg_row_len*t2.filas_crec_proyectada)/1024/1024)*
decode(t2.periodo_crec_proyectado,'D',30,'S',4.3,'M',1,'A',1/12)+t3.bytes/1024/1024)*l_coef_ajuste,2) "Proy 1Mes",
round((((t1.avg_row_len*t2.filas_crec_proyectada)/1024/1024)*
decode(t2.periodo_crec_proyectado,'D',90,'S',13,'M',3,'A',1/4)+t3.bytes/1024/1024)*l_coef_ajuste,2) "Proy 3Mes",
round((((t1.avg_row_len*t2.filas_crec_proyectada)/1024/1024)*
decode(t2.periodo_crec_proyectado,'D',180,'S',26,'M',6,'A',1/2)+t3.bytes/1024/1024)*l_coef_ajuste,2) "Proy 6Mes",
round((((t1.avg_row_len*t2.filas_crec_proyectada)/1024/1024)*
decode(t2.periodo_crec_proyectado,'D',365,'S',52,'M',12,'A',1)+t3.bytes/1024/1024)*l_coef_ajuste,2) "Proy 1Año"
from user_tables t1,
tbl_sizing_config t2,
user_segments t3
where t1.table_name = t2.table_name
and t1.table_name = t3.segment_name);

dbms_output.put_line('TOTALES (Incluye estimación sobre el total de tablas de la Aplicación)');
dbms_output.put_line('------- ');
dbms_output.put_line('Total Alocado Actualmente : 'l_Aloc_Act*(1+(100-&PctTabs)/100)' Mb');
dbms_output.put_line('Total Proyectado a 1 Mes : 'to_char(l_sum_pmes1*(1+(100-&PctTabs)/100))' Mb');
dbms_output.put_line('Total Proyectado a 3 Meses: 'to_char(l_sum_pmes3*(1+(100-&PctTabs)/100))' Mb');
dbms_output.put_line('Total Proyectado a 6 Meses: 'to_char(l_sum_pmes6*(1+(100-&PctTabs)/100))' Mb');
dbms_output.put_line('Total Proyectado a 1 Año : 'to_char(l_sum_paño*(1+(100-&PctTabs)/100))' Mb');
end;
/