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.