Hive не отображает объединение небольшой таблицы против объединения двух больших таблиц.

У меня есть 3 небольших таблицы: smallTable0, smallTable1 и smallTable3. Все они имеют менее 100 строк и одинаковые схемы. Еще у меня есть 3 больших стола: largeTable0, largeTable1 и largeTable3. Все они имеют более 1 миллиона строк, имеют идентичные схемы, разделяют столбец id с небольшими таблицами, разделены на что-то иное, чем id (в случае, если разбиение имеет значение, я подозреваю, что это не так).

После установки hive.auto.convert.join=true следующие случаи приводят к MapJoin, как и ожидалось:

  • Присоединение к smallTable0 против smallTable1
  • Присоединение к smallTable0 против largeTable0
  • Присоединяясь к smallTable0 против smallTable1 UNION ALL smallTable2

Следующие случаи не приводят к MapJoin, как ожидалось:

  • Присоединение largeTable0 против чего угодно.
  • Присоединение к smallTable0 против чего-либо с hive.auto.convert.join=false

Однако неожиданно следующий случай также не приводит к MapJoin:

  • Присоединение smallTable0 против largeTable0 UNION ALL largeTable1

Точный запрос выглядит следующим образом:

SELECT * FROM smallTable0 s
JOIN (
  SELECT * FROM (
    SELECT * FROM largeTable0
    UNION ALL
    SELECT * FROM largeTable1 
  ) x
) l
  ON s.id = l.id;

Он работает нормально, но с Common Join вместо MapJoin, что снижает производительность. Создание представления, представляющего largeTable0 UNION ALL largeTable1, не решает проблему. Я уверен, что создание таблицы, которая largetTable0 UNION ALL largeTable1, решит проблему, но дублирование такого большого количества данных с последующей их синхронизацией нежелательно.

Исходный код для оператора Union (здесь) есть комментарий, который я считаю несколько загадочным.

/**
* Union operators are not allowed either before or after a explicit mapjoin hint.
* Note that, the same query would just work without the mapjoin hint (by setting
* hive.auto.convert.join to true).
**/
@Override
public boolean opAllowedBeforeMapJoin() {
  return false;
}

@Override
public boolean opAllowedAfterMapJoin() {
  return false;
}

Кажется, предполагается, что оператор UNION не разрешен с явной подсказкой MapJoin, но что оператор UNION разрешен с MapJoins, инициированным в результате hive.auto.convert.join. Однако я не понимаю, почему одно может быть разрешено, а другое запрещено. Если «просто работать» не означает, что запрос будет «работать», только не с MapJoin. Однако, если бы это было так, я ожидал бы, что присоединение smallTable0 к smallTable1 UNION ALL smallTable2 приведет к общему соединению.

Является ли странное поведение результатом ошибки в Hive, ошибки в моем коде, отсутствующей функции в Hive или недопонимания с моей стороны?


person Daniel Koverman    schedule 03.05.2013    source источник


Ответы (1)


Вы можете указать Hive подсказки для обработки таблиц во время объединения. Я всегда указываю MAPJOIN или STREAMTABLE, если я знаю, является ли небольшая таблица кандидатом на присоединение, или очень большая таблица, которая должна быть передана другим пользователям.

e.g.

SELECT /*+ MAPJOIN(smalltable0) */ * FROM smallTable0 s
person libjack    schedule 07.05.2013