У меня есть 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 или недопонимания с моей стороны?