jan 252016
 

Se tentarmos criar um índice numa coluna já indexada no Oracle 11g vamos receber o seguinte erro:

ORA-01408: such column list already indexed

No Oracle 12c isso não acontece.

O 12c trouxe inúmeras features e uma delas é a possibilidade de criar mais de um índice numa mesma coluna.

Mas por que alguém faria isso ?


Disponibilidade e performance.

Como assim ?

Performance

Vamos supor que você tenha feito testes em desenvolvimento e tenha identificado que um índice do tipo bitmap é mais performático do que um B-Tree.

Como validar isso em produção ? No Oracle 11g, voce teria que dropar o índice B-Tree, e só assim criar o índice do tipo bitmap.

No Oracle 12c você não tem esse problema, você pode criar o índice bitmap deixando-o invisível, daí fazer os testes e decidir qual índice manter.

Disponibilidade

Vamos supor que você precise trocar o tipo de um índice como descrito no cenário acima, ou então trocar um índice de non-unique para unique, de não particionado para particionado e etc.

No 11g e anteriores, essa ação exigiria pelo menos 2 passos:

  • Dropar indice anterior
  • Criar indice novo

O problema é que entre dropar o índice e criar o novo , você ficaria sem índice na tabela. Caso o índice seja grande e leve 15 minutos para ser criado, voce ficaria 15 minutos sem índice. Isso poderia ser muito critico em algumas aplicações.

Com o 12c você não tem esse problema.

No 12 você poderia fazer assim:

  • Criar indice novo como invisível
  • Alterar índice que desejar apagar para invisível
  • Alterar índice novo para visível

É quase que instantâneo !

Em ação

Mas que tal vermos isso tudo na prática ?

Vamos criar uma tabela grande, criar um índice non-unique nela, e depois trocar esse índice para unique usando essa nova feature do 12c.

Criando big table

Para isso podemos usar os script fornecidos no post “Criando uma tabela para testes no Oracle – bigtable”.
Eu usei o script com uma pequena modificação:

CREATE TABLE bigtab (
id NUMBER,
weight NUMBER,
adate DATE
);

INSERT INTO bigtab (id, weight, adate)
SELECT rownum,
DBMS_RANDOM.RANDOM,
SYSDATE-1000+DBMS_RANDOM.VALUE(0,1000)
FROM all_objects
/

Criando índice non-unique

Para todas as ações eu vou usar o timing.
Lembrando que eu poderia criar os indices usando paralelismo para acelerar o processo.

SQL> create index bigtab_non_unique_1 on bigtab(id);

Index created.

Elapsed: 00:00:00.23

Criando índice unique

No 11g levaríamos um erro aqui:

SQL> create unique index bigtab_unique_2 on bigtab(id) invisible;
create unique index bigtab_unique_2 on bigtab(id) invisible
                                              *
ERROR at line 1:
ORA-01408: such column list already indexed

Elapsed: 00:00:00.19

Mas no 12c isso não acontece:

SQL> create unique index bigtab_unique_2 on bigtab(id) invisible;

Index created.

Elapsed: 00:00:00.18

Note que o índice esta sendo criado invisível, caso contrario levaríamos o ORA-01408.

Alterando índice non-unique para invisível

SQL> alter index bigtab_non_unique_1 invisible;

Index altered.

Elapsed: 00:00:00.03

Alterando índice non-unique para visível

SQL> alter index bigtab_unique_2 visible;

Index altered.

Elapsed: 00:00:00.00

Vocês podem ver que o processo de alterar o índice para visível e invisível é muito rápido…

Sem dúvida essa nova feature vai nos ajuda em muitos casos !

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)