Otimização de junção distorcida usando dicas de inclinação

Este artigo descreve como usar dicas de distorção para melhorar a distorção de dados em uma tabela, uma condição que pode prejudicar o desempenho da consulta.

Observação

As dicas join distorcida não são necessárias. A distorção é resolvida automaticamente se a execução query adaptativa (AQE) e spark.sql.adaptive.skewJoin.enabled estiverem ativados. Consulte Execução query adaptativa.

O que é distorção de dados?

A distorção de dados é uma condição na qual os dados de uma tabela são distribuídos de forma desigual entre as partições nos clusters. A distorção de dados pode prejudicar gravemente o desempenho da query, especialmente aquelas com join. join entre tabelas grandes requer embaralhamento de dados e a distorção pode levar a um desequilíbrio extremo de trabalho nos clusters. É provável que a distorção de dados esteja afetando uma query se uma query parecer travada ao terminar poucas tarefas (por exemplo, as últimas 3 tarefas de 200). Para verificar se a distorção de dados está afetando uma query:

  1. Clique no estágio que está travado e verifique se ele está fazendo uma join.

  2. Após a conclusão query , localize o estágio que faz uma join e verifique a distribuição da duração da tarefa.

  3. Classifique as tarefas diminuindo a duração e verifique as primeiras tarefas. Se uma tarefa levou muito mais tempo para ser concluída do que as outras tarefas, há distorção.

Para melhorar a distorção, o Delta Lake no Databricks SQL aceita dicas de distorção em query. Com as informações de uma dica de inclinação, o Databricks Runtime pode construir um plano query melhor, que não sofra com distorção de dados.

Configurar dica de inclinação com nome de relação

Uma dica de inclinação deve conter pelo menos o nome da relação com inclinação. Uma relação é uma tabela, view ou uma subconsulta. Todos join com essa relação e usam a otimização join de inclinação.

-- table with skew
SELECT /*+ SKEW('orders') */
  *
  FROM orders, customers
  WHERE c_custId = o_custId

-- subquery with skew
SELECT /*+ SKEW('C1') */
  *
  FROM (SELECT * FROM customers WHERE c_custId < 100) C1, orders
  WHERE C1.c_custId = o_custId

Configurar dica de inclinação com nome de relação e nomes de coluna

Pode haver join múltipla em uma relação e apenas algumas delas sofrerão de distorção. A otimização de join de inclinação tem alguma sobrecarga, portanto, é melhor usá-la somente quando necessário. Para esse propósito, a dica de inclinação aceita nomes de colunas. join somente com essas colunas usa a otimização join de inclinação.

-- single column
SELECT /*+ SKEW('orders', 'o_custId') */
  *
  FROM orders, customers
  WHERE o_custId = c_custId

-- multiple columns
SELECT /*+ SKEW('orders', ('o_custId', 'o_storeRegionId')) */
  *
  FROM orders, customers
  WHERE o_custId = c_custId AND o_storeRegionId = c_regionId

Configurar dica de inclinação com nome de relação, nomes de coluna e valores de inclinação

Você também pode especificar valores de inclinação na dica. Dependendo da query e dos dados, os valores de inclinação podem ser conhecidos (por exemplo, porque nunca mudam) ou podem ser fáceis de descobrir. Isso reduz a sobrecarga da otimização join inclinação. Caso contrário, o Delta Lake os detecta automaticamente.

-- single column, single skew value
SELECT /*+ SKEW('orders', 'o_custId', 0) */
  *
  FROM orders, customers
  WHERE o_custId = c_custId

-- single column, multiple skew values
SELECT /*+ SKEW('orders', 'o_custId', (0, 1, 2)) */
  *
  FROM orders, customers
  WHERE o_custId = c_custId

-- multiple columns, multiple skew values
SELECT /*+ SKEW('orders', ('o_custId', 'o_storeRegionId'), ((0, 1001), (1, 1002))) */
  *
  FROM orders, customers
  WHERE o_custId = c_custId AND o_storeRegionId = c_regionId