2013-05-03 4 views
0

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

После установки 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, решит проблему, но дублирование большого количества данных, а затем их синхронизация нежелательно.

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

/** 
* 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; 
} 

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

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

ответ

1

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

например.

SELECT /*+ MAPJOIN(smalltable0) */ * FROM smallTable0 s