domingo, 27 de abril de 2014

12c - Statistics During Loads

No Oracle Database 12c, foi introduzida uma nova feature, Online Statistics Gathering for Bulk Loads.

O banco de dados irá coletar estatísticas automaticamente das tabelas durante os seguintes tipos de operações bulk load:

  • CREATE TABLE AS SELECT

  • INSERT INTO ... SELECT into an empty table using a direct path insert

Por padrão, parallel inserts usam direct path insert. Podemos forçar o direct path insert usando o hint  / * + APPEND * /.

Lembrando que ao coletar as estatísticas, o banco de dados não irá gerar histograms e nem coletar estatísticas para índices existentes. Para isso é necessário utilizar o DBMS_STATS.

Para a criação de índices, desde a versão 10G o Oracle automaticamente coleta as estatísticas do índice após a sua criação.

Para voltar a ter o comportamento anterior à release 12c e não coletar as estatísticas, podemos utilizar o hint NO_GATHER_OPTIMIZER_STATISTICS.




SQL> create table tabela_teste
(
coluna1 number,
coluna2 number
);
Table created.

SQL> begin
for i in 1..1000
loop
insert into tabela_teste values(i, i);
end loop;

commit;
end;
/
PL/SQL procedure successfully completed.

SQL> select count(*) from tabela_teste;
COUNT(*)
----------
1000


Podemos verificar que não existem estatísticas, pois foi um insert normal:

SQL> select table_name, num_rows, last_analyzed from user_tables where table_name='TABELA_TESTE';

TABLE_NAME                     NUM_ROWS   LAST_ANALYZED
------------------------------ ---------- -------------
TABELA_TESTE


Agora utilizando CTAS:

SQL> create table tabela_teste2 as select * from tabela_teste;
Table created.

SQL> select table_name, num_rows, last_analyzed from user_tables where table_name='TABELA_TESTE2';

TABLE_NAME                     NUM_ROWS   LAST_ANALYZED
------------------------------ ---------- -------------
TABELA_TESTE2                  1000       16-APR-14




Utilizando direct path insert:

SQL> create table tabela_teste3
(
  coluna1 number,
  coluna2 number
);
Table created.
 
SQL> insert /*+ APPEND */ into tabela_teste3 select object_id,object_id from user_objects where rownum < 30;
25 rows created.
 
SQL> select table_name, num_rows, last_analyzed from user_tables where table_name='TABELA_TESTE3';
 
TABLE_NAME                           NUM_ROWS         LAST_ANALYZED
------------------------------       ----------        -------------
TABELA_TESTE3                               25         16-APR-14 10:20:00
 
 

Quando a tabela não está vazia, as estatísticas não são atualizadas:

SQL> insert /*+ APPEND */ into tabela_teste3 select object_id,object_id from user_objects where rownum < 30;
25 rows created.

SQL> select table_name, num_rows, last_analyzed from user_tables where table_name='TABELA_TESTE3';

TABLE_NAME                     NUM_ROWS   LAST_ANALYZED
------------------------------ ---------- -------------
TABELA_TESTE3 25               16-APR-14  10:20:00


Verificando o plano de execução:

SQL> explain plan for
create table tabela_teste4 as select * from tabela_teste;

Explained.

SQL> select * from table(dbms_xplan.display(null, null, 'BASIC'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1183779688

------------------------------------------------------------------
| Id | Operation | Name |
------------------------------------------------------------------
| 0 | CREATE TABLE STATEMENT | |
| 1 | LOAD AS SELECT | TABELA_TESTE2 |
| 2 | OPTIMIZER STATISTICS GATHERING | |
| 3 | TABLE ACCESS FULL | TABELA_TESTE |
------------------------------------------------------------------

10 rows selected.



Obtendo informações sobre a coleta automática de estatísticas:

SQL> select table_name, column_name, num_distinct, notes from user_tab_col_statistics where table_name = ('TABELA_TESTE3');

TABLE_NAME           COLUMN_NAME          NUM_DISTINCT NOTES
-------------------- -------------------- ------------ ------------------------------
TABELA_TESTE3        COLUNA1              25            STATS_ON_LOAD
TABELA_TESTE3        COLUNA2              25            STATS_ON_LOAD


Para restrições na coleta automática, consultar a referência abaixo.


Referências:



Abraço,


Alex Zaballa

0 comentários: