Quando uma operação JOIN apresenta baixo desempenho devido a valores de chave frequentes (hot keys), isole essas chaves para melhorar a eficiência. O SKEWJOIN HINT divide os dados em duas partes — uma para os valores de chave frequentes e outra para os dados restantes —, processa cada parte separadamente e mescla os resultados. Esse hint detecta automaticamente ou permite que você especifique manualmente os valores de chave frequentes para acelerar o join.
Uso
Para utilizar esse recurso, adicione o SKEWJOIN HINT no formato /*+ skewJoin(<table_name>[(<column1_name>[,<column2_name>,...])][((<value11>,<value12>)[,(<value21>,<value22>)...])]*/ à sua instrução select. No hint, table_name indica a tabela com skew, column_name define a coluna com skew e value especifica o valor da chave com skew.
-- Method 1: Specify the table name (note that you must hint the table alias).
select /*+ skewjoin(a) */ * from T0 a join T1 b on a.c0 = b.c0 and a.c1 = b.c1;
-- Method 2: Specify the table and the columns that you suspect are skewed. For example, columns c0 and c1 in table 'a' are skewed.
select /*+ skewjoin(a(c0, c1)) */ * from T0 a join T1 b on a.c0 = b.c0 and a.c1 = b.c1 and a.c2 = b.c2;
-- Method 3: Specify the table, columns, and the exact skewed key values. If a value is a STRING type, enclose it in double quotation marks. For example, the values in (a.c0=1 and a.c1="2") and (a.c0=3 and a.c1="4") cause data skew.
select /*+ skewjoin(a(c0, c1)((1, "2"), (3, "4"))) */ * from T0 a join T1 b on a.c0 = b.c0 and a.c1 = b.c1 and a.c2 = b.c2;
O Método 3, no qual você especifica explicitamente os valores das chaves com skew, é mais eficiente que o Método 1 e o Método 2.
Funcionamento
Um valor de chave frequente (hot key) é uma chave que aparece com alta frequência. Por exemplo, na figura a seguir, a seção vermelha mostra 10.000 linhas onde a.c0=1 and a.c1=2 e 9.000 linhas onde a.c0=3 and a.c1 = 4.
Sem o SKEWJOIN HINT, unir as tabelas grandes T0 e T1 exige um MERGE JOIN. Esse processo redistribui todos os valores idênticos de chaves frequentes para um único nó, o que causa skew de dados. Ao adicionar o SKEWJOIN HINT, o otimizador executa uma operação de agregação para identificar dinamicamente os 20 principais valores de chaves frequentes com base na frequência. Em seguida, ele divide a tabela T0 em dois conjuntos de dados: um com os valores de chaves frequentes (Dados A) e outro com os valores restantes (Dados B). Da mesma forma, divide a tabela T1 em linhas que correspondem aos valores de chaves frequentes de T0 (Dados C) e nas linhas restantes (Dados D). Depois, realiza um MAP JOIN nos Dados A e Dados C. Como o conjunto de dados C é pequeno, o MAP JOIN torna-se eficiente. Posteriormente, executa um MERGE JOIN nos Dados B e Dados D. Por fim, combina os resultados do MAP JOIN e do MERGE JOIN usando uma operação UNION ALL para gerar o resultado final, conforme ilustrado na figura a seguir.
Observações
-
O SKEWJOIN HINT oferece suporte aos seguintes tipos de JOIN:
INNER JOIN: aplique o hint em qualquer uma das tabelas do join.
LEFT JOIN, SEMI JOIN e ANTI JOIN: o hint deve ser aplicado apenas à tabela esquerda.
RIGHT JOIN: restrinja a aplicação do hint à tabela direita.
FULL JOIN: este tipo de join não tem suporte.
Adicione o hint somente a joins que comprovadamente causam skew de dados. O hint inicia uma operação de agregação, o que gera sobrecarga adicional. Além disso, para uma consulta como
A JOIN B, adicionar um SKEWJOIN HINT à tabela A força um plano de execução física semelhante aMAP JOIN UNION ALL MERGE JOIN. O subplano do MAP JOIN se expande para um plano similar aTop 20(A) MAP JOIN (B SEMI JOIN Top20(A)). Se a tabela B for grande e o resultado filtrado dela também for extenso, a operação de MAP JOIN poderá causar um erro de falta de memória (OOM) durante a criação da tabela hash.-
No join com hint, os tipos de dados das chaves de junção dos lados esquerdo e direito devem corresponder. Caso contrário, o SKEWJOIN HINT não surte efeito. Utilize a função CAST dentro de uma subconsulta para garantir a consistência dos tipos de dados, conforme os exemplos abaixo:
create table T0(c0 int, c1 int, c2 int, c3 int); create table T1(c0 string, c1 int, c2 int); --Method 1: select /*+ skewjoin(a) */ * from T0 a join T1 b on cast(a.c0 as string) = cast(b.c0 as string) and a.c1 = b.c1; --Method 2: select /*+ skewjoin(b) */ * from (select cast(a.c0 as string) as c00 from T0 a) b join T1 c on b.c00 = c.c0; Após a adição do SKEWJOIN HINT, o otimizador executa uma operação de agregação para identificar os 20 principais valores de chaves frequentes. O valor 20 é o padrão. Altere essa configuração executando o comando
set odps.optimizer.skew.join.topk.num = xx;.Aplique o SKEWJOIN HINT a apenas uma tabela por join.
O join com hint deve ser uma equijunção que inclua a condição
left key = right key. Operações CARTESIAN JOIN não são suportadas.-
Combine o SKEWJOIN HINT com outros hints, conforme o exemplo a seguir. No entanto, não adicione um SKEWJOIN HINT a um join que já contenha um hint MAP JOIN.
select /*+ mapjoin(c), skewjoin(a) */ * from T0 a join T1 b on a.c0 = b.c3 join T2 c on a.c0 = c.c7; Verifique se o SKEWJOIN HINT está ativo pesquisando o campo topk_agg na aba Json Summary do Logview.