Mais um blog inútil.

Outubro 5, 2009

Hash Joins – Oracle (e talvez outros)

Filed under: Serious Business — drune @ 20:36

Estava aqui a ver um filme estúpido na SIC, enquanto o meu browser crashou com um pdf e então lembrei me logo de blogar sobre hash joins.

A primeira regra para se usar um hash join em detrimento de outras opções para uma operação de join é o pressuposto que ambas as tabelas têm que ter uma quantidade de dados significativa, ou seja, “grandes” tabelas.

Normalmente o optimizador da BD opta pelo uso de hash join quando não existem indices apropriados, quando o fracção de dados a juntar é grande ou simplesmente porque o conceito de ALL_ROWS está definido para o output do join e uma das anteriores condições é valida.
Numa fase inicial e quando se opta pelo hash join, o motor da BD lê a menor tabela da operação de join e coloca-a na memória. O conceito básico será a criação de um hash key por linha que servirá posteriormente para fazer o join. Essa hash table é guardada em memória e é APENAS gerada com base nas chaves existentes na tabela, chaves essas que irão ser usadas para o join com a tabela maior.

Mas perguntam vocês, mas então e se não for possível colocar as hash key na memória?

Existe efectivamente um limite de 200Mb no Oracle 10, ou seja 5% do pga_aggregate_target ou o valor da hash_area_size. Senão for possível alocar essas hash keys no limite definido o CBO (Cost based optimizer) do Oracle vai optar por não escolher um hash join já que a operação não será de todo possível ou então irá recorrer a uso do tablespace TEMP para colocar o que falta degradando assim a performance da operação.
É por norma algo dificil saber ajustar os parametros do hash_area_size que define para cada sessão o valor máximo de hash area a usar, mas usa-se convencionalmente a seguinte formula para o cálculo:

hash_area_size = 1.6 x nr de linhas da tabela menor.

Imaginemos que será possível guardar todo o conteudo da hash table em memória, o próximo passo será ler a tabela maior em FULL TABLE SCAN normalmente. Para cada hash key presente na memória o motor tentará fazer um match com a hash gerada a partir das chaves da tabela maior. Em ambas as tabelas é sempre gerada uma hash key por cada linha para permitir a comparação, excepto que é colocada na memória e outra no disco.

Performance:

Pode-vos parecer um pouco estúpido por exemplo obrigar um full table scan numa tabela como exemplo de 700 milhões de registos. Realmente, não é muito esperto até que alguém se lembrou de introduzir o conceito de paralelismo. É um conceito a explicar detalhadamente noutro post, mas com cpu’s e RAM suficientes é possível obter resultados impressionantes face ao volume de dados a ler.

Xau.

Comentar

widgeon
widgeon
widgeon
widgeon