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 ? >