O crescimento descontrolado do banco de dados é uma grande dor de cabeça que o DBA enfrenta em seu dia a dia. Se tratando ainda de uma base de produção, onde existe uma grande volumetria de dados, a fragmentação é um problema muito comum. Esse é um dos itens que vem à cabeça quando o DBA trabalha para melhorar a organização das tablespaces (subdivisão lógica de um banco para organizar estruturas lógicas que são relacionadas).
As constantes operações DML (Data Manipulation Language – operações de leitura e escrita de dados) sofridas nas tabelas e índices de um banco de dados proporcionam um crescimento do espaço utilizado por eles. Porém, muitas vezes esse crescimento não se apresenta por conta da alta volumetria de dados, mas sim pelo surgimento de fragmentação dos espaços que não são utilizados pelos dados das tabelas. Com isso, a área das populares “marcas d’água” ou “high water mark” vai aumentando.
A marca d’água é o último bloco onde o objeto termina dentro da tablespace e é uma área que tende a ter a mesma quantidade de informações do objeto. Quando uma tabela, um índice ou um range de dados sofre um delete, os segmentos de dados ficam cheios de blocos vazios que são reutilizados apenas depois de um insert ou update, ou às vezes nem são reutilizados. Se a tabela/índice sofre muitas dessas operações DML, os números desses blocos vazios e inutilizados se acumulam com o decorrer do tempo, aumentando a área de dados fragmentados.
Isso pode acarretar no desempenho negativo em queries de selects (Full Table Scan), pois a consulta deverá percorrer uma área maior de blocos para retornar o valor desejado. Operações de alter table também são prejudicadas, pois a movimentação entre os blocos tende a ficar mais lenta. Além disso, inserts e updates ficam mais lentos na execução, pois buscam preencher os blocos vazios. Por fim, o índice pode sofrer um desbalanceamento, o que prejudica seu uso e faz com que o espaço físico utilizado por ele seja perdido.
Neste contexto, o Shrink é utilizado para fazer a reorganização desses objetos, liberando o espaço inutilizado, diminuindo o tamanho de blocos vazios e desfragmentando os dados. Entre suas vantagens, podemos destacar:
· Pode ser executado com os serviços de banco de dados em estado open e com usuários conectados. Assim, não há a necessidade de fazer shutdown ou desconexão de usuários para executar essa tarefa;
· Em outras técnicas de desfragmentação de dados, como o MOVE TABLESPACE ou DBMS_REDEFINITION, existe a necessidade de espaço físico extra em disco para executar as operações. Porém, isso não se aplica ao Shrink.
Apesar de muito útil, o Shrink possui algumas limitações:
· Não funciona em Cluster tables, tabelas que contenham colunas do tipo long, tabelas e índices baseados em funções e com características IOT;
· A tabela deverá estar com o recurso de Row movement habilitado. Essa propriedade permite a reorganização de linhas da tabela. Por default, a mesma vem desabilitada quando efetuado o Create Table;
· Não funciona em tablespaces configuradas para gerenciamento manual de espaço;
· Quando executado, o Shrink faz lock no objeto referido, sendo aplicado para tabelas ou índices. Ou seja, a tabela associada fica bloqueada para sofrer qualquer alteração DDL ou DML.
Desfragmentando tabelas na prática
Para demonstrar o uso do Shrink, iremos criar uma tabela de teste para melhor exemplificar a visão da compactação, como pode ser visto na Listagem 1.
Listagem 1. Create table da tabela TESTESHRINK
1 SQL> CREATE TABLE TESTESHRINK
2 (
3 ID NUMBER NOT NULL,
4 VALOR NUMBER (10, 2) NOT NULL ENABLE,
5 data DATE NOT NULL ENABLE,
6 NOME VARCHAR2 (50) NOT NULL ENABLE,
7 CONSTRAINT TESTE_SH PRIMARY KEY (id)
8 );
9
10 Table created
Os campos são nomes genéricos e foram criados apenas para uma melhor simulação de uma tabela de pr ...