segunda-feira, 1 de agosto de 2011

Tabelas em Clusters

Olá Pessoal.
Continuando a saga de Posts realacionados aos tipos de Tabelas no Oracle, hoje irei comentar sobre os Clusters de Tabelas.

O Cluster é um objeto de esquema que armazena duas ou mais tabelas no mesmo  bloco ou segmento,  ou seja  você tem dados de muitas tabelas compartilhando o mesmo bloco de dados fisicamente.
Um Cluster auxilia nas leituras de tabelas que contenham colunas relacionadas e são normalmente acessadas juntas assim possibilita menos I/O na Base de dados.
Podemos usar como exemplo as nossas amigas e velhas conhecidas tabelas de teste do Oracle a EMP e DEPT.  Caso quiséssemos unir estas duas tabelas  em um Cluster usaríamos a coluna DEPTNO que é comum nas duas tabelas  e será determinada como a chave do cluster.
A chave de um cluster não poderá ter valores repetidos, caso seja necessário mais colunas para unir as tabelas, uma chave de Cluster composite de 32 colunas poderá ser utilizada.

Claro que nem tudo são flores existem limitações a serem avaliadas antes de utilizar as tabelas em clusters. São elas:
·         Os tipos de dados LONG, LOB, LONG ROW não são suportados dentro de um cluster.
·         Caso haja a necessidade de consultar somente uma tabela do cluster o desempenho da consulta tende a piorar, pois não há como extrair as linhas de uma tabela sem trazer as linhas pertencentes à outra tabela que faz parte do cluster, por isso pense bem antes de sair criando.
·         Operações DML também podem causar um impacto referente às tabelas armazenadas nos clusters.

Os tipos de Clusters mais utilizados são:
·         Cluster de Índice é o tipo padrão e requer que um índice de cluster seja criado para o Cluster.
·         Cluster de Hash, a chave do cluster é convertida em um valor de hash e será armazenada no cluster com base neste valor não havendo a necessidade de criação de um índice para o cluster, ou seja, utiliza uma função hashing para armazenar e recuperara as linhas em uma tabela.
·         Cluster de Hash Classificado também utiliza uma função hashing para armazenar e recuperara as linhas, além disso, permite que as linhas sejam armazenadas por uma ou mais colunas das tabelas em ordens crescentes. Também a adição de um parâmetro SORT depois das definições de colunas dentro do cluster para indicar a ordem pela qual a classificação ira seguir.

Oracle Quick Tip: O parâmetro HashKeys Permite definir quantos valores de Hash deve ser alocado à tabela.
Bom vcs devem estar se perguntando e quando devemos usar cada um desses tipos de clusters.
No caso do Cluster de Índice, devemos levar em consideração a varredura de intervalos e os predicados de desigualdade utilizados na chave de cluster.
Já no cluster de Hash o ideal é que o predicado de igualdade seja utilizado nas colunas de clusters.

Para que possamos utilizar estes recursos devemos seguir alguns passos:

1-Passo Temos que criar um objeto Cluster para ser utilizado pela tabela, o comando utilizado é o CREATE CLUSTER.

2-Criar as tabelas que participarão do Cluster, o comando utilizado é o CREATE TABLE.

3-Caso seja um Cluster de Índice temos que criar um Índice para o Cluster, o comando utilizado é o CREATE INDEX.

Oracle Quick Tip: Para criar um Cluster em seu Schema será necessário o privilégio de sistema CREATE CLUSTER, caso seja em um outro schema  CREATE ANY CLUSTER. Também deverá ter cota alocada no Tablespace utilizado.

EXEMPLO: 

Na minha base de dados de Teste eu tenho 2 tabelas Heaps (ITEM_MASTER,ITEM_SALE).

SQL> select count(*) from  ITEM_MASTER ;
  COUNT(*)
----------
      3500

SQL> select count(*) from ITEM_SALE ;
  COUNT(*)
----------
   4001994

Para o nosso exemplo irei criar 2 tabelas com as mesmas estruturas e quantidades de Dados que as tabelas Heaps para que possamos compará-las.
Vamos lá chega de Teoria!!!

1-Criação do Cluster

SQL> CREATE CLUSTER testecluster(
ITEM_ID NUMBER) HASHKEYS 3500; 
Cluster created.

2-Criação da Tabela mãe associada ao objeto  Cluster  testecluster.

CREATE TABLE ITEM_MASTER_CLUSTER
(ITEM_ID    NUMBER,ITEM_NAME  VARCHAR2(30 ) NOT NULL )                
CLUSTER TESTECLUSTER(ITEM_ID)
NOCOMPRESS ;
 ALTER TABLE ITEM_MASTER_CLUSTER ADD (
PRIMARY KEY
(ITEM_ID));

 3-Criação da Tabela Filha  associada ao objeto  Cluster  testecluster.

CREATE TABLE ITEM_SALE_CLUSTER 
( ITEM_SALE_ID    NUMBER,
 ITEM_ID         NUMBER,
 ITEMS_SOLD      NUMBER,
 ITEM_SALE_DATE  DATE,
 ITEM_SOLD_TO    NUMBER)
CLUSTER TESTECLUSTER(ITEM_ID)
NOCOMPRESS ;
ALTER TABLE ITEM_SALE_CLUSTER ADD (
PRIMARY KEY
(ITEM_SALE_ID))
ALTER TABLE ITEM_SALE_CLUSTER ADD (
FOREIGN KEY (ITEM_ID)
REFERENCES TEM_MASTER (ITEM_ID));

4-Quantidade total de registros nas Tabelas de Clusters :

SQL> select count(*) from  ITEM_MASTER_CLUSTER ;
 COUNT(*)
----------
3500

SQL> select count(*) from ITEM_SALE ;
 COUNT(*)
----------
 4001994

 5-Gerei um Plano de Execução em uma declaração Select  utilizando as tabelas HEAPS e as Tabelas Clusters para compararmos qual solução será  mais viável.

A-Explain , Query utilizando as tabelas em Clusters.

SQL> explain plan for  SELECT *
FROM  ITEM_MASTER_CLUSTER  A ,ITEM_SALE_CLUSTER  B
WHERE A.ITEM_ID =  B.ITEM_ID
ORDER BY A.ITEM_ID ;
Explained.

SQL> set pagesize 1000
SQL> set linesize 300
SQL> select * from table(dbms_xplan.display);








B-Explain , Query utilizando as tabelas Heaps.

SQL> explain plan for  SELECT *
FROM  ITEM_MASTER   A ,ITEM_SALE  B
WHERE A.ITEM_ID =  B.ITEM_ID
ORDER BY A.ITEM_ID ;
Explained.

SQL> select * from table(dbms_xplan.display);










Percebam que após a analisarmos os dois planos de execução, a query que utliza as tabelas em clusters teve o melhor custo e o menor tempo de processamento.

Claro que este é somente um cenário ipotético , devemos considerar a volumetria e granularidade dos dados em nossa base. E sempre testar , testar e testar......

Oracle Quick Tip : Para eliminar tabelas que pertencem a um cluster, devemos eliminar o cluster para o qual as tabelas estão associadas, com a Clausúla DROP CLUSTER  testecluster INCLUDING TABLES CASCADE ;

Referências :
http://download.oracle.com/docs/

Obrigada!

2 comentários:

  1. Olá Luciana !

    Ao criar o cluster testecluster foi especificado HASHKEYS 3500
    que é número de linhas da tabela, mas num caso real, a tabela cresce todos os dias, tem que atualizar o HASHKEYS de tempos em tempos ?

    Att,

    Sakamoto

    MyTraceLog - Registro de um DBA
    http://mytracelog.blogspot.com

    ResponderExcluir
  2. Olá Sakamoto !

    Obrigada pela Leitura.
    Em Relação a sua Pergunta antes de criar um Cluster Hash o ideal é que seja informado a quantidade de linhas que a tabela irá receber pelo Arquiteto da Aplicação.No caso da tabela crescer fora das estimativas , o único jeito de mudar o Parametro HASHKEYS é dropando e recriando o Cluster.
    De uma lida neste link:
    http://download.oracle.com/docs/cd/B12037_01/server.101/b10759/statements_5001.htm
    Muito Obrigada.

    ResponderExcluir