quinta-feira, 7 de abril de 2011

Métodos de Joins no Oracle Parte III


HASH JOIN
Os dois conjuntos de dados processados por um Hash Join são chamados de build input e probe input. A build input é a esquerda, e a probe input é a entrada à direita. Como ilustrado na Figura abaixo, usando cada linha da entrada da build input, uma tabela hash na memória (ou espaço temporário, se não há memória suficiente está disponível) é construída.
Observe que a chave de hash usada para esse fim é calculada com base nas colunas usadas como condição de join. Uma vez que a tabela hash contém todos os dados do build input, o processamento da probe input começa.
Cada linha é testada contra a tabela hash, a fim de descobrir se ele cumpre a condição de join. Obviamente, apenas registros coincidentes são retornados.


                * Visão do processo de um Hash Join

Hash Joins são caracterizados pelas seguintes proriedades :
·         Cada operação Filha só é executada uma vez
·         A tabela hash é construída sobre a entrada da esquerda. Por conseqüência , é geralmente construída na menor entrada.
·         Antes de retornar a primeira linha, somente a entrada deesquerda deve ser totalmente processado.
·         Cross joins, theta joins e partitiouned outer joins não são suportados.
Exemplo de Hash Join.
O exemplo a seguir é um simples plano de execução mostrando o processamento de um Hash Joins entre duas tabelas, O exemplo também mostra como forçar uma hash join por meio das dos hints leading  e use_hash.

SQL_IRAJA  > SELECT /*+ leading(t1) use_hash(t2) */ *
FROM t1, t2
WHERE t1.id = t2.t1_id
AND t1.n = 19
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    10 |  1180 |    30   (4)| 00:00:01 |
|*  1 |  HASH JOIN         |      |    10 |  1180 |    30   (4)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |    57 |     5   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL| T2   |   100 |  6100 |    24   (0)| 00:00:01 |
---------------------------------------------------------------------------

   1 - access("T1"."ID"="T2"."T1_ID")
   2 - filter("T1"."N"=19)

 O processamento do plano de execução pode ser resumido da seguinte forma  :

·         Todas as linhas da tabela t1 são lidas através de um full table scan, a restrição n = 19 é aplicada, e uma tabela de hash é construído com as linhas resultantes.  Para construir a tabela de hash, uma função hash é aplicada para as colunas usadas na condição de join (id).
·         Todas as linhas da tabela T2 são ligas através de um full table scan, uma função hash é aplicada para as colunas usadas na condição de join (t2_id) e a tabela de hash entra no modo probed. Se for encontrado os dados correspondentes as linhas são retornadas

A limitação mais importante para a operação HASH JOIN (como para as outras operações combinadas não relacionadas) é a incapacidade de tirar proveito dos índices para aplicar nas condições de join. Isto significa que os índices podem ser utilizados como caminho de acesso somente se as restrições estão disponíveis. Por exemplo, se a restrição n = 19 fornece boa seletividade, pode ser útil para criar um índice para aplicá-la.

SQL_IRAJA > CREATE INDEX t1_n ON t1 (n)

In fact, with this index in place, the following execution plan might be used. Note that the
table t1 is no longer accessed through a full table scan.

Na verdade, com esse índice em vigor, o plano de execução a seguir pode ser usado. Observe que a tabela t1 já não é mas acessada através de um full table scan.

-------------------------------------------------------------------------------------                                                                                                                                                          
| Id  | Operation                    | Name | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                                                                          
-------------------------------------------------------------------------------------                                                                                                                                                          
|   0 | SELECT STATEMENT             |      |    10 |  1180 |    27   (4)| 00:00:01 |                                                                                                                                                           
|*  1 |  HASH JOIN                   |      |    10 |  1180 |    27   (4)| 00:00:01 |                                                                                                                                                           
|   2 |   TABLE ACCESS BY INDEX ROWID| T1   |     1 |    57 |     2   (0)| 00:00:01 |                                                                                                                                                           
|*  3 |    INDEX RANGE SCAN          | T1_N |     1 |       |     1   (0)| 00:00:01 |                                                                                                                                                           
|   4 |   TABLE ACCESS FULL          | T2   |   100 |  6100 |    24   (0)| 00:00:01 |                                                                                                                                                           
-------------------------------------------------------------------------------------                                                                                                                                                           
                                                                                                                                                
   1 - access("T1"."ID"="T2"."T1_ID")                                                                                                                                                                                                          
   3 - access("T1"."N"=19)    









Nenhum comentário:

Postar um comentário