Colega, antes de entramos na questão, a pergunta que não quer (e não pode se) 
calar : vc ** TEM ** uma evidência Exata, Reproduzível e Significativa de 
performance diferente nos seus SQLs principais após a recriação das tais 
tabelas , OU vc está se dando ao trabalho só porque viu em algum lugar que isso 
deve ser feito ????? Pois é um trabalho Gigantesco em bases maiores/mais 
exigentes, se vc não mede o retorno do investimento, vc  ** Não ** tem como o 
justificar... Essa evidência não precisa ser nada tão sofisticado quanto um 
trace, pode ser simplesmente diminuição do número de I/Os, do tempo de CPU ou 
do tempo gasto na V$SQL para o mesmo SQL, pode um plano diferente antes & 
depois do rebuild (plano real, capturado/exibido com o 
dbms_xplan.display_cursor), pode ser uma diferença apreciável pra menos nas v$  
de waits e estatísticas da sessão, qquer coisa assim, reproduzível e 
tecnicamente assertiva...
 
 Muito bem : SUPONDO que vc tem a evidência, o primeiro Fato a notar é que 
há/podem haver  ** DIVERSAS ** issues de I/O ao se acessar tabelas no RDBMS 
Oracle, e SHRINKs / REBUILDs (além do COALESCE e das  alterações de parâmetros 
de storage, tipo pctfree/pctused, que vc não cita  mas deveria) atacam ** 
DIFERENTES ** pontos : vc Necessariamente TEM QUE descobrir qual é o ponto que 
está causando o problema que vc evidenciou, okdoc ? Chamar tudo de 
"FRAGMENTAÇÃO" é por demais genérico... Isso serve pra quando vc está passando 
um conceito de modo superficial (eu mesmo confesso, mais de uma vez numa 
reunião com analistas tasquei o termo "fragmentação" pra eles poderem entender 
de modo geral a questão), mas aqui nós estamos entre profissionais de banco de 
dados, vamos então definir com exatidão o que pode ocorrer E o que vc faz pra 
cada caso...
 Vamos lá :
 
 1. espaço livre não usado por diferença de tamanho de extents : isso ocorre 
quando a tablespace possui extents livres de tamanhos totalmente diferentes e 
não-múltiplos entre si E diferentes do extent requerido na tabela - digamos, a 
tablespace tem livres vários extents de 19 Kb, de 45 Kb, e de 1,5 Mb, digamos, 
mas a tabela pede pra alocar extents de 1 Mb : evidentemente não dá pra 
quebrar/subdividir extents, então o RDBMS ** vai ** formatar e alocar um extent 
novo quando precisar crescer, DESPREZANDO os que já existem, causando 
desperdício de espaço e (em caso de Full Table Scan ou similares) causando 
extents quase sem dados , ou mesmo sem dados, serem lidos... Esta issue é a que 
normalmente é chamada de fragmentação nas conversas de usuário e em livros 
genéricos...
 Solução : usar tablespace LMT, nas tablespaces LMT vc *** Obrigatoriamente ** 
ou tem extents iguais (se vc optar por indicar o tamanho, com o UNIFORM SIZE) 
ou tem extents de poucos tamanhos e  MÚLTIPLOS entre si (se optar por 
AUTOALLOCATE), com tamanhos automaticamente criados e tipo de 16 Kb, 32 Kb, 64 
Kb, 1 Mb (aonde os menores  PODEM ser coalescidos pra se criar os maiores), 
então com isso vc torna IMPOSSÍVEL o problema ocorrer ...
 
 2. tamanho de extent muito menor do que o máximo I/O possível no sistema 
operacional : isso é problema quando vc vai fazer SCANs (Full Table Scan, 
principalmente)  , caso onde o RDBMS vai ler não blocos, mas extents inteiros : 
se vc tiver uma tabela de 100 Mb, o máximo de I/O que o SO pode fazer é 1 Mb, 
digamos, MAS os seus extents são todos de 64 Kb, no caso de FTS ao invés do SO 
fazer 100 I/OS de 1 Mb, ele VAI TER que fazer 1600 (se minhas contas estão 
corretas :) I/Os de 64 Kb ..... Não é uma issue frequente mas pode ocorrer...
 Solução : além de usar LMT, ou use LMTs AUTOALLOCATE (nessas tablespaces o 
RDBMS segue um algoritmo que força o crescimento do extent size cfrme a tabela 
cresce , até chegar no 1 Mb que é o máximo de I/O típico na maioria dos SOs) , 
ou se for usar UNIFORM SIZE tenha CERTEZA de como serão usados e até onde vão 
crescer os objetos que vc botar em tablespaces LMT UNIFORM SIZE, os maiores/com 
mais tendência a crescer (e portanto a pedir por FTS) ** deveriam ** ser 
colocados em LMT uniform de 1 Mb, OU múltiplos de 1 Mb ...
 
 3. quantidade anormalmente grande de extents : isso era uma preocupação com as 
tablespaces antigas, as DMT (gerenciadas por dicionário), pois nelas haviam 
tabelas internas (sys.uet$, sys.fet$, e outras) que continham os extents livres 
& usados, aí a cada acesso a uma tabela de usuário as tabelas internas tinham 
que ser acessadas, a cada alteração de dados em tabelas de usuários o novo 
consumo de extents tinha que ser inserido nas tabelas internas, era bem fácil 
vc ter problemas de concorrência interna com isso .... as tablespaces LMT usam 
um bitmap interno pra se controlar, é mais rápido e menos propenso à 
concorrência... 
   Solução : usar tablespaces LMT ** E ** se atentar ao item 2. acima :  já que 
os objetos maiores são mais propensos a FTS, se vc tem um extent size bem 
ajustado (ou usa AUTOALLOCATE), o extent maior vai naturalmente levar á uma 
quantidade menor de extents nos objetos grandes , normalmente só isso já deixa 
a quantidade de extents num nível gerenciável pelos bitmaps...
   
4. high-water mark mais alto do que o necessário : ao se fazer um INSERT /*+ 
APPEND */ , o APPEND significa que o RDBMS ** não ** vai reaproveitar os 
extents livres que já estejam reservados pra tabela, e sim vai requisitar novos 
extents da lista de espaço livre, vai usá-los pra guardar os dados e vai 
adicionar (APPEND) esses extents ao "final" da tabela... Imagine que vc, após 
vários DELETEs (vide item 5., abaixo) vc tem a tabela fisicamente em disco tipo 
abaixo (X são blocos com dados, e os pontos são blocos vazios) :

XXXXXXXXXXXXX
XX...........................
XXXXX...................
...............................
...............................
X

o APPEND necessariamente vai criar novos  extents/blocos, desprezando os que já 
estão livres, tipo :

XXXXXXXXXXXXX
XX...........................
XXXXX...................
...............................
...............................
XXXXXXXXXXXX
XXXXXXXXXXXX
XXXXXXXXXXXX

Isso é problema ?? DEPENDE : se após esse APPEND, vc sabe que no futuro breve 
vão ser feitos INSERTs normais (vide item 5. abaixo) os espaços livres VÂO SIM 
ser re-usados, no problema... 
A Solução , se não vão haver INSERTs normais depois do APPEND , E vc comprovou 
que esses white-spaces tão interferindo (nos seus FTSs, provavelmente, ou no 
seu consumo de disco), pode ser :

  a. pedir um TRUNCATE ao invés de DELETE , antes da carga (APPEND tipicamente 
são feitos em carga massiva de dados)
  
  ou
  
  b. liberação física dos extents : isso pode ser feito com SHRINK (** se ** o 
ROW MOVIMENT está habilitado na tabela, e as demais exigências estão 
atendidads, checar manual de Concepts no item "Space Reclamation" , OU com o 
rebuild mesmo .... A diferença desses dois é que, cfrme o manual cita, o SHRINK 
abaixa o HWM liberando os extents que estão entre o último efetivamente usado e 
o HWM : os eventuais vazios "no meio" da tabela não necessariamente serão 
reusados e irão pro free space, a única maneira de vc re-aproveitar esse espaço 
se vc sabe que não haverão mais INSERTs normais) é mesmo re-alocar os blocos, 
via REBUILD.... 
  
  =====>> ESSA é sua resposta parcial sobre SHRINK x REBUILD, ie, DEPNDE DO QUE 
VC QUER : se vc quer baixar a HWM ou quer efetivamente reusar os extents no 
"meio" da tabela, vc TEM QUE analisar aí o seu caso das suas tabelas pra poder 
entender / descobrir qual o comando que se ajusta melhor ao seu caso...
  
    
  5. white-space / espaço não usado após DELETEs :  esta issue é ao que 
normalmente a Oracle se refere como "fragmentação" - sim, mesmo a Oracle é 
culpada de super-simplificar e chamar de fragmentação sem explicar o que é... 
   Isto tem que ser bem definido, é um dos pontos aonde vc mais besteira vê por 
aí - o que ocorre é que, após deleções de dados, os blocos/extents que 
continham dados do objeto que sofreu o DELETE ** vão ** continuar marcados como 
reservados/pertencentes ao objeto : isso é pra Acelerar os futuros INSERTs, com 
isso ao invés do RDBMS ter que formatar blocos novos (o que teria que fazer se 
os blocos que sofreram DELETE fossem liberados pro sistema após o DELETE) , o 
INSERT reusa simplesmente o espaço que o DELETE liberou... 
  Isso é CRÍTICO pra entendermos : se a tabela X sofreu DELETEs e algum espaço 
está disponível pra ela, ** NECESSARIAMENTE ** e Obrigatoriamente os próximos 
INSERTs vão sim reusar esse espaço disponível, esse espaço ***** NÂO **** está 
morto, ele VAI SIM ser reusado, okdoc ? A besteira principal que vc vai ouvir é 
que após DELETEs o espaço não pode ser reusado, fica 'perdido' e isso é um tipo 
de "fragmentação".... 
  Muito bem, mas e nos casos aonde o objeto/segmento sofreu DELETEs 
significativos , e (por regra de negócio) vc SABE que nunca mais serão 
inseridos novos dados - tipo, é uma tabela particionada que só contém pos dados 
de Outubro, e o mês de outubro acabou ? Aí sim, esse Sim é um caso onde vc sabe 
o que o RDBMS Oracle não sabe, vc tem certeza que aquele espaço reservado mas 
vazio não vai ser nunca reusado pelos novos INSERTs por força de uma regra 
lógica externa ao banco, aí sim se vc quiser/precisarliberar esse espaço vc TEM 
que tomar uma ação.... Notar que, além de desperdício de espaço em disco, esse 
white-space VAI influenciar em FTSs ...
  Solução : as mesmas do item acima , que (Novamente) só podem;devem ser 
aplicadas SE e APENAS SE vc realmente sabe que não haverão INSERTs reusando 
esse espaço em branco...
  
  6. white-space/espaço reservado/não usado em Blocos, causando algum tipo de 
migração de dados : o espaço nos blocos normalmente não é usado do começo ao 
fim, há algum espaço reservado para futuros UPDATEs : caso esse espaço seja 
muito grande, na hora dum INSERT de uma linha um tantinho maior não haverá 
espaço pra gravar no bloco, a linha será "continuada" em um novo bloco, aí 
eventuais leituras dessa linha passam a exigir mais de um acesso à blocos - 
multiplique isso por milhões de linhas, E tenha uma Aplicação vagal que faz 
leitura de muitos dados row by row (via CURSOR, provavelmente) pra processar, e 
vc terá um grande problema em mãos...
   Solução : CONHECER a utilização que a tabela terá e especificar 
PCTFREE/PCTUSEd adequados, ou (em alguns casos, se viável) tentar usar ASSM...
   
   
Em termos gerais é isso , minha Recomendação é lapidar :

 R1 : obtenha Comprovação de que há diferença Apreciável quando vc faz o REBUILD
 
 R2 : antes de pensar em automatizar, descubra Exatamente qual a issue que está 
"pegando", já que cfrme eu disse em alguns casos há parâmetro/ação que ELIMINA 
o problema, ao invés de ficar tolamente e cegamente fazendo rebuilds e rebuilds 
sem pensar

[]s

  Chiappa

--- Em oracle_br@yahoogrupos.com.br, "candiurudba" <candiurudba@...> escreveu
>
> Bom dia colegas,
> 
> Estou pensando em automatizar o processo de desfragmentação de tabelas do meu 
> RAC.
> 
> O volume de transações aumentou consideravelmente e por este motivo, todos os 
> finais de semana estou tendo que executar manualmente procedimentos para 
> desfragmentar as tabelas, o que tem tomado muito do meu tempo.
> 
> Alguêm teria alguma forma de uma verificação mais simples destas fragmentação 
> para que eu possa gerar um script agendado no CRON ?
> 
> Uma outra dúvida é quanto os procedimentos para reorganização das tabelas 
> fragmentadas. Sempre utilizei o comando MOVE com o rebuild dos indices e 
> todos sabemos que ele (muitas vezes) é extremamente consumidor (CPU), gerando 
> problemas tambem nos indices, sendo necessário o rebuild dos mesmos.
> 
> Andei lendo alguma coisa sobre SHRINK SPACE COMPACT para reorganização das 
> linhas nas tabelas, eliminando a fragmentação existente e depois SHRINK SPACE 
> para mexer na HWM. Teoricamente estes comandos em conjunto, deixam as tabelas 
> em funcionamento para operação DML, não consomem tanto recursos de maquina, 
> alem de não deixarem os indices como UNUSABLE. Seria isto mesmo ?
>


Responder a