out 102014
 

Você descobre que um índice vai te ajudar naquele relatório que dura horas.

Você planeja a execução, mas dai se pergunta se tem espaço suficiente em disco, pois a tabela é gigantesca.

Já enfrentou alguma situação parecida ?

Existem várias técnicas que podem ser usadas aqui, uma delas é usar a package dbms_space.

É verdade que ela tem as suas limitações e não é 100% precisa, mas ela pode dar uma boa ajuda.

Para chama-la é muito fácil.

Primeiramente eu configuro o ambiente:

    
SQL> create table test_table (column_1 number);

Table created.

SQL> insert into test_table values (1);

1 row created.

SQL> commit;

Commit complete.

SQL> exec dbms_stats.gather_table_stats('CAUDURO','TEST_TABLE');

PL/SQL procedure successfully completed.

Crio uma tabela com apenas uma linha a principio e vamos ver o que a package nos informa:


SQL> set serveroutput on

SQL>
declare 

    l_used number;

    l_alloc number;

begin

    dbms_space.create_index_cost(ddl => 'create index test_index on 
                           test_table (column_1) tablespace users',                                         used_bytes => l_used,
                                 alloc_bytes => l_alloc
    );

    dbms_output.put_line('Bytes usados: '  || l_used);
    dbms_output.put_line('Bytes alocados: ' || l_alloc);

end;
/

Bytes usados: 3
Bytes alocados: 65536

PL/SQL procedure successfully completed.

SQL> 

SQL> select initial_extent from dba_tablespaces where tablespace_name='USERS';
INITIAL_EXTENT
--------------
	 65536
 

Você pode perceber que os tamanhos retornados para Used e allocated são diferentes.

Na verdade used indica o quanto o índice ocupa em dados, mas o allocated mostra o quanto o Oracle vai precisar no disco para criar aquele índice, levando em conta o space management da tablespace.

Notem que o tamanho do extent inicial da tablespace é o tamanho inicial da tabela. Então dependendo da tablespace, você pode precisar de mais espaço ou menos espaço.

Agora eu insiro algumas linhas na tabela e refaço o teste:


SQL> select count(*) from test_table;

  COUNT(*)
----------
	 1

SQL> 
SQL> 
SQL> begin

for c in 1..1000000 loop

    insert into test_table values (c);

end loop; 

end;

/

commit;
  
PL/SQL procedure successfully completed.

Commit complete.
 
SQL> select count(*) from test_table;

  COUNT(*)
----------
   1000001

SQL> exec dbms_stats.gather_table_stats('CAUDURO','TEST_TABLE');

PL/SQL procedure successfully completed.

SQL> declare 

    l_used number;

    l_alloc number;

begin

    dbms_space.create_index_cost(ddl => 'create index test_index on 
                         test_table (column_1) tablespace users',                                           used_bytes => l_used,
                                 alloc_bytes => l_alloc
    );

    dbms_output.put_line('Bytes usados: '  || l_used);
    dbms_output.put_line('Bytes alocados: ' || l_alloc);

end;
/  
  
Bytes usados: 5000005
Bytes alocados: 25165824

PL/SQL procedure successfully completed.

Com essa quantidade de linhas vamos precisar muito mais do que apenas um extent.

Serão necessários 25165824 bytes, ou 24 megas, para criar esse índices.

O que achou ?
Esta conseguindo estimar os seus índices ?

Espero que tenham gostado.

 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)