Perigos e Armadilhas do Particionamento - Etapa 2 – Parte 03

por Arup Nanda 

Rule Based Optimizer (Otimizador Baseado em Regras)

Podemos usar particionamento com o Rule Based Optimizer (RBO)? A resposta é: claro que podemos. Porém, quando o particionamento foi introduzido, o RBO foi considerado legado, e a Oracle decidiu que gradativamente fosse encerrado o suporte ao mesmo. Isto conduziu a uma interrupção geral no desenvolvimento de RBO, portanto hoje, RBO não é utilizado para desenvolvimentos interessantes, inclusive o particionamento. Então, para obter completa vantagem do particionamento (poda de partição (partition prune), junções expertas de partição (partition wise join) e assim por diante), você tem que usar o Cost Based Optimizer (CBO). Se você usa o RBO, e uma tabela na consulta é particionada, o Oracle passa para o CBO enquanto está otimizando. Mas como as estatísticas não estão presentes, o CBO compõe as estatísticas, e isto poderia conduzir a planos de otimização extremamente caros e com desempenho extremamente pobre.

Assim, embora seja possível, não deveríamos aplicar particionamento ao usar o RBO. 

Coalesce vs. Merge (Fusão x Combinação)

Estas duas declarações potencialmente confusas servem para o mesmo propósito - reduzir o número de partições - e são aplicáveis em esquemas diferentes. Em uma faixa - ou tabela particionada por lista (list-partitioned table), os limites da partição estão claramente definidos, e as linhas em uma partição satisfazem alguma condição dependente nos valores de limite. ALTER TABLE … MERGE PARTITION une as duas partições adjacentes e estabelece os limites adequadamente. 

Consideremos o exemplo de uma PART de tabela (table PART) que é particionada por faixa em quatro partições diferentes chamadas P1, P2, P3 e P4. Para combinar (merge) as partições P3 e P4 e obter uma partição chamada P34, execute a seguinte declaração:

ALTER TABLE PART MERGE PARTITIONS P3, P4 INTO PARTITION P34;

Porém, em tabelas particionadas por hash não há valores de limite e as linhas não são selecionadas como candidatas para as partições com base em algum tipo de faixa definida. Assim, um merge não poderá identificar e fixar limites específicos. Deveriamos usar uma cláusula nova chamada COALESCE para atingir este objetivo: 

ALTER TABLE PART COALESCE;

Com COALESCE, uma partição específica, normalmente a última, é selecionada para eliminação. Supõe-se que todas as linhas naquela partição são distribuídas igualmente através das partições restantes e a partição é eliminada. Na prática, porém, as linhas são combinadas (merged) com a partição adjacente. 

Considerando que isto reduz o número de partições em uma, o número total não mais é uma potência de dois, provocando uma distribuição de linhas desigual em todas as partições. Para evitar este problema, executamos o COALESCE mais uma mais vez para obter partições uniformemente carregadas. 

Em resumo, MERGE usa-se para particionamento por faixa ou lista quando os valores são claramente identificados por valores limite, e COALESCE usa-se para partições baseadas em hash, para reduzir o número de partições. 

Outras Dúvidas

Sobre Rebuild Partition e Global Indexes (Reconstrução de Partição e Índices Globais)

O Oracle9iR2 oferece agora cisão de particionamento rápida (fast split partitioning). Tipicamente, durante uma operação de cisão, o Oracle cria duas partições novas e então redistribui as linhas da partição fonte para as novas partições. Esta é uma operação muito cara do ponto de vista de consumo de recursos. Além disso, partições de índice locais (local index partitions) ficam inutilizáveis. 

Com a cisão de particionamento rápida, se todas as linhas existem na mesma partição após a cisão da partição, o Oracle simplesmente re-utiliza de novo a velha partição e cria uma partição vazia. Assim, uma ação de cisão representa mais uma operação completa do que a criação de uma partição nova. 

Índices globais ficam inutilizáveis quando uma partição é reconstruída. Porém, no 9i, uma nova cláusula atualiza os índices globais também. 

ALTER TABLE PTAB DROP PARTITION P2 UPDATE GLOBAL INDEXES;

Ao usarmos particionamento, deveríamos utilizar bind variables (variáveis de ligação)? 

Esta é uma pergunta interessante. Como nós já sabemos, o uso de variáveis de ligação elimina a necessidade de analisar gramaticalmente os cursores e torna mais fácil a re-utilização dos mesmos. 

No caso de partições, porém, o uso de variáveis de ligação conduz a uma situação problemática. Junções e eliminação de partições só podem acontecer se o optimizer souber com antecedência o predicado de filtragem. O valor das variáveis de ligação não é conhecido até chegar a hora da execução, tornando inviável o processo de junção ou eliminação de partição. Então, para tirar proveito destas opções, não deveríamos usar variáveis de ligação. 

No Oracle 9i, a primeira análise gramatical (parse) da declaração, chamada de análise gramatical hard (hard parse), verifica o valor da variável de ligação e pode efetuar estas opções de otimização. Mas isto só acontece com a análise gramatical hard; análises gramaticais subseqüentes ainda mexem com os valores das variáveis de ligação. 

Quantas partições podem ser definidas em uma tabela? 

O Oracle usa um campo de dois bytes para armazenar o número de segmentos (partições ou sub-partições) o que habilita 2^16 ou 65536 espaços. Então, o código do Oracle permite um pouco menos que este valor: 65535. Note-se que este é um limite designado pelo código de software do Oracle; o limite real pode ser menor.

Lembremos que toda vez que uma consulta é analisada gramaticalmente em um objeto particionado, a metadata (i.e., quantas partições e assim por diante) é carregada no cache de cursor no SGA, significando que o SGA deverá ser grande o suficiente para manipular uma tabela com várias partições.