Поделиться через


Оптимизация соединения с отклонением с помощью подсказок с размыка

Внимание

Поддержка этой документации прекращена, она может больше не обновляться. Продукты, службы или технологии, упоминание в этом содержимом больше не поддерживаются.

Намеки на присоединение не требуются. Databricks обрабатывает отклонение по умолчанию с помощью адаптивного выполнения запросов (AQE). См. статью Адаптивное выполнение запросов.

Примечание.

spark.sql.adaptive.skewJoin.enabled должен быть True, который является параметром по умолчанию в Azure Databricks.

Что такое неравномерное распределение данных?

Неравномерное распределение данных — это условие, при котором данные таблицы неравномерно распределяются между секциями в кластере. Неравномерное распределение данных может значительно снизить производительность запросов, особенно с объединениями. Для объединений больших таблиц требуются перемешивание данных, а неравномерное распределение может привести к значительному различию в объеме работ в кластере. Если в ходе выполнения запроса не удается завершить небольшое количество задач (например, последних 3 задач из 200), вероятно, вы столкнулись с неравномерным распределением данных. Чтобы проверить это, выполните следующие действия:

  1. Нажмите зависший этап и убедитесь, что в нем выполняется объединение.
  2. После завершения запроса найдите этап, на котором выполняется объединение, и проверьте распределение длительности задач.
  3. Отсортируйте задачи по убыванию длительности и проверьте первые несколько задач. Если выполнение одной задачи заняло больше времени по сравнению с другими, это говорит о наличии неравномерного распределения.

Чтобы устранить неравномерное распределение, в Delta Lake в Azure Databricks SQL можно отправлять указание в запросах. Так Databricks Runtime сможет лучше спланировать запрос, чтобы устранить негативные последствия неравномерного распределения данных.

Настройка указания о неравномерном распределении по имени отношения

Указание о неравномерном распределении должно содержать по крайней мере имя отношения с неравномерным распределением. Отношение — это таблица, представление или вложенный запрос. Все объединения с этим отношением используют оптимизацию объединения неравномерного распределения.

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

Настройка указания о неравномерном распределении по имени отношения и именам столбцов

В отношении может содержаться несколько объединений, и только в некоторых из них может быть неравномерное распределение. Оптимизация объединения неравномерного распределения связана с временными затратами, поэтому лучше использовать ее только при необходимости. Для этого в указании о неравномерном распределении можно задавать имена столбцов. Только для объединений с этими столбцами будет применяться оптимизация.

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

Настройка указания о неравномерном распределении по имени отношения, именам столбцов и значениям неравномерного распределения

В указании также можно задавать значения неравномерного распределения. В зависимости от запроса и данных значения неравномерного распределения могут быть известны (например, так как они никогда не изменяются), или их можно легко найти. Это снижает временные затраты на оптимизацию объединения неравномерного распределения. В противном случае Delta Lake автоматически обнаруживает их.

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