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.
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)